diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2024-02-19 17:35:12 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2024-03-04 16:13:50 +0000 |
| commit | 1e57df19697fd4f7f1e9dfd24ccfb00051c25bda (patch) | |
| tree | f0730d02b56b2eb8d180b1845f8e0a88557b3938 /compiler | |
| parent | f2612daf58bfa2d747ddae02243a6ec1d6528992 (diff) | |
| download | rust-1e57df19697fd4f7f1e9dfd24ccfb00051c25bda.tar.gz rust-1e57df19697fd4f7f1e9dfd24ccfb00051c25bda.zip | |
Add a scheme for moving away from `extern "rust-intrinsic"` entirely
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/intrinsic.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/cross_crate_inline.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/lib.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/collector.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 |
11 files changed, 59 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 84269ec2942..9b8167fa2bf 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1255,7 +1255,17 @@ fn codegen_regular_intrinsic_call<'tcx>( // Unimplemented intrinsics must have a fallback body. The fallback body is obtained // by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`. - _ => return Err(Instance::new(instance.def_id(), instance.args)), + _ => { + let intrinsic = fx.tcx.intrinsic(instance.def_id()).unwrap(); + if intrinsic.must_be_overridden { + span_bug!( + source_info.span, + "intrinsic {} must be overridden by codegen_cranelift, but isn't", + intrinsic.name, + ); + } + return Err(Instance::new(instance.def_id(), instance.args)); + } } let ret_block = fx.get_block(destination.unwrap()); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 2dba04e0bb7..347a968a303 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -16,6 +16,7 @@ use rustc_middle::ty::{self, SymbolName, TyCtxt}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; use rustc_middle::util::Providers; use rustc_session::config::{CrateType, OomStrategy}; +use rustc_span::sym; use rustc_target::spec::{SanitizerSet, TlsModel}; pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { @@ -81,6 +82,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S return library.kind.is_statically_included().then_some(def_id); } + if tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden) { + return None; + } + // Only consider nodes that actually have exported symbols. match tcx.def_kind(def_id) { DefKind::Fn | DefKind::Static(_) => {} diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e1150904bd1..1875d06d669 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -903,7 +903,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { MergingSucc::False }; } - Err(instance) => Some(instance), + Err(instance) => { + if intrinsic.must_be_overridden { + span_bug!( + span, + "intrinsic {} must be overridden by codegen backend, but isn't", + intrinsic.name, + ); + } + Some(instance) + } } } }; diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 10867ae230a..de7ea84ffa5 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -867,6 +867,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, "#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen" ), + rustc_attr!( + rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, + "the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies", + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index fdb2b4f2024..8c2b5413fa0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1051,13 +1051,18 @@ fn should_encode_mir( // Coroutines require optimized MIR to compute layout. DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true), // Full-fledged functions + closures - DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { + def_kind @ (DefKind::AssocFn | DefKind::Fn | DefKind::Closure) => { let generics = tcx.generics_of(def_id); - let opt = tcx.sess.opts.unstable_opts.always_encode_mir + let mut opt = tcx.sess.opts.unstable_opts.always_encode_mir || (tcx.sess.opts.output_types.should_codegen() && reachable_set.contains(&def_id) && (generics.requires_monomorphization(tcx) || tcx.cross_crate_inlinable(def_id))); + if matches!(def_kind, DefKind::AssocFn | DefKind::Fn) { + if let Some(intrinsic) = tcx.intrinsic(def_id) { + opt &= !intrinsic.must_be_overridden; + } + } // The function has a `const` modifier or is in a `#[const_trait]`. let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id()) || tcx.is_const_default_method(def_id.to_def_id()); diff --git a/compiler/rustc_middle/src/ty/intrinsic.rs b/compiler/rustc_middle/src/ty/intrinsic.rs index f5df687d923..18d08ed23a5 100644 --- a/compiler/rustc_middle/src/ty/intrinsic.rs +++ b/compiler/rustc_middle/src/ty/intrinsic.rs @@ -5,6 +5,8 @@ use super::TyCtxt; #[derive(Copy, Clone, Debug, Decodable, Encodable, HashStable)] pub struct IntrinsicDef { pub name: Symbol, + /// Whether the intrinsic has no meaningful body and all backends need to shim all calls to it. + pub must_be_overridden: bool, } impl TyCtxt<'_> { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e64f69a4461..19724b2e83a 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1646,7 +1646,10 @@ pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) || tcx.has_attr(def_id, sym::rustc_intrinsic) { - Some(ty::IntrinsicDef { name: tcx.item_name(def_id.into()) }) + Some(ty::IntrinsicDef { + name: tcx.item_name(def_id.into()), + must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden), + }) } else { None } diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 483fd753e70..e2730c156c3 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -23,6 +23,10 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return false; } + if tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden) { + return false; + } + // This just reproduces the logic from Instance::requires_inline. match tcx.def_kind(def_id) { DefKind::Ctor(..) | DefKind::Closure => return true, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 86f37456183..37d087a4696 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -632,6 +632,12 @@ fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> { } fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { + if let Some(attr) = tcx.get_attr(did, sym::rustc_intrinsic_must_be_overridden) { + span_bug!( + attr.span, + "this intrinsic must be overridden by the codegen backend, it has no meaningful body", + ) + } if tcx.is_constructor(did.to_def_id()) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 5593de60784..b3a28b546d3 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1019,6 +1019,11 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> return false; } + if tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden) { + // These are implemented by backends directly and have no meaningful body. + return false; + } + if def_id.is_local() { // Local items cannot be referred to locally without monomorphizing them locally. return true; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7e31cfc0662..73088d2cf7b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1525,6 +1525,7 @@ symbols! { rustc_inherit_overflow_checks, rustc_insignificant_dtor, rustc_intrinsic, + rustc_intrinsic_must_be_overridden, rustc_layout, rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_start, |
