From 7f9830b16c4da25220974229f252ee1840acf4c2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 17:39:04 +0000 Subject: [PATCH 1/5] Make `const_eval_select` a rustc_intrinsic --- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 +- compiler/rustc_middle/src/hir/map/mod.rs | 4 +- library/core/src/intrinsics.rs | 130 ++++++++++-------- .../effects/minicore.rs | 24 ++-- 5 files changed, 95 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 35755a46df3a4..7a1fe3b1cdc4d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -579,7 +579,7 @@ pub fn check_intrinsic_type( sym::is_val_statically_known => (1, 1, vec![param(0)], tcx.types.bool), - sym::const_eval_select => (4, 0, vec![param(0), param(1), param(2)], param(3)), + sym::const_eval_select => (4, 1, vec![param(0), param(1), param(2)], param(3)), sym::vtable_size | sym::vtable_align => { (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d8cfceab460a0..68911f579cd93 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1704,8 +1704,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { for &local_def_id in tcx.mir_keys(()) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { - record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- - self.tcx.deduced_param_attrs(local_def_id.to_def_id())); + if tcx.intrinsic(local_def_id).map_or(true, |i| !i.must_be_overridden) { + record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- + self.tcx.deduced_param_attrs(local_def_id.to_def_id())); + } } } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 5043bd855ccb9..57a88a0310919 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1365,7 +1365,9 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { if associated_body(Node::ImplItem(item)).is_some() { - self.body_owners.push(item.owner_id.def_id); + if !self.tcx.has_attr(item.owner_id.def_id, sym::rustc_intrinsic_must_be_overridden) { + self.body_owners.push(item.owner_id.def_id); + } } self.impl_items.push(item.impl_item_id()); diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index f939720287fd4..9a7ade8a83727 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2508,62 +2508,7 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn vtable_align(ptr: *const ()) -> usize; - /// Selects which function to call depending on the context. - /// - /// If this function is evaluated at compile-time, then a call to this - /// intrinsic will be replaced with a call to `called_in_const`. It gets - /// replaced with a call to `called_at_rt` otherwise. - /// - /// This function is safe to call, but note the stability concerns below. - /// - /// # Type Requirements - /// - /// The two functions must be both function items. They cannot be function - /// pointers or closures. The first function must be a `const fn`. - /// - /// `arg` will be the tupled arguments that will be passed to either one of - /// the two functions, therefore, both functions must accept the same type of - /// arguments. Both functions must return RET. - /// - /// # Stability concerns - /// - /// Rust has not yet decided that `const fn` are allowed to tell whether - /// they run at compile-time or at runtime. Therefore, when using this - /// intrinsic anywhere that can be reached from stable, it is crucial that - /// the end-to-end behavior of the stable `const fn` is the same for both - /// modes of execution. (Here, Undefined Behavior is considered "the same" - /// as any other behavior, so if the function exhibits UB at runtime then - /// it may do whatever it wants at compile-time.) - /// - /// Here is an example of how this could cause a problem: - /// ```no_run - /// #![feature(const_eval_select)] - /// #![feature(core_intrinsics)] - /// # #![allow(internal_features)] - /// # #![cfg_attr(bootstrap, allow(unused))] - /// use std::intrinsics::const_eval_select; - /// - /// // Standard library - /// # #[cfg(not(bootstrap))] - /// pub const fn inconsistent() -> i32 { - /// fn runtime() -> i32 { 1 } - /// const fn compiletime() -> i32 { 2 } - /// - // // ⚠ This code violates the required equivalence of `compiletime` - /// // and `runtime`. - /// const_eval_select((), compiletime, runtime) - /// } - /// # #[cfg(bootstrap)] - /// # pub const fn inconsistent() -> i32 { 0 } - /// - /// // User Crate - /// const X: i32 = inconsistent(); - /// let x = inconsistent(); - /// assert_eq!(x, X); - /// ``` - /// - /// Currently such an assertion would always succeed; until Rust decides - /// otherwise, that principle should not be violated. + #[cfg(bootstrap)] #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn const_eval_select( @@ -2576,6 +2521,79 @@ extern "rust-intrinsic" { F: FnOnce; } +/// Selects which function to call depending on the context. +/// +/// If this function is evaluated at compile-time, then a call to this +/// intrinsic will be replaced with a call to `called_in_const`. It gets +/// replaced with a call to `called_at_rt` otherwise. +/// +/// This function is safe to call, but note the stability concerns below. +/// +/// # Type Requirements +/// +/// The two functions must be both function items. They cannot be function +/// pointers or closures. The first function must be a `const fn`. +/// +/// `arg` will be the tupled arguments that will be passed to either one of +/// the two functions, therefore, both functions must accept the same type of +/// arguments. Both functions must return RET. +/// +/// # Stability concerns +/// +/// Rust has not yet decided that `const fn` are allowed to tell whether +/// they run at compile-time or at runtime. Therefore, when using this +/// intrinsic anywhere that can be reached from stable, it is crucial that +/// the end-to-end behavior of the stable `const fn` is the same for both +/// modes of execution. (Here, Undefined Behavior is considered "the same" +/// as any other behavior, so if the function exhibits UB at runtime then +/// it may do whatever it wants at compile-time.) +/// +/// Here is an example of how this could cause a problem: +/// ```no_run +/// #![feature(const_eval_select)] +/// #![feature(core_intrinsics)] +/// # #![allow(internal_features)] +/// # #![cfg_attr(bootstrap, allow(unused))] +/// use std::intrinsics::const_eval_select; +/// +/// // Standard library +/// # #[cfg(not(bootstrap))] +/// pub const fn inconsistent() -> i32 { +/// fn runtime() -> i32 { 1 } +/// const fn compiletime() -> i32 { 2 } +/// +// // ⚠ This code violates the required equivalence of `compiletime` +/// // and `runtime`. +/// const_eval_select((), compiletime, runtime) +/// } +/// # #[cfg(bootstrap)] +/// # pub const fn inconsistent() -> i32 { 0 } +/// +/// // User Crate +/// const X: i32 = inconsistent(); +/// let x = inconsistent(); +/// assert_eq!(x, X); +/// ``` +/// +/// Currently such an assertion would always succeed; until Rust decides +/// otherwise, that principle should not be violated. +#[rustc_const_unstable(feature = "const_eval_select", issue = "none")] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[cfg(not(bootstrap))] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn const_eval_select( + _arg: ARG, + _called_in_const: F, + _called_at_rt: G, +) -> RET +where + G: FnOnce, + F: FnOnce, +{ + unreachable!() +} + /// Returns whether the argument's value is statically known at /// compile-time. /// diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index 1b380c989fa4a..281cfdaef28cc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -509,17 +509,19 @@ trait StructuralPartialEq {} const fn drop(_: T) {} -extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")] - #[rustc_safe_intrinsic] - fn const_eval_select( - arg: ARG, - called_in_const: F, - called_at_rt: G, - ) -> RET - where - F: const FnOnce, - G: FnOnce; +#[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")] +#[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic] +const fn const_eval_select( + arg: ARG, + called_in_const: F, + called_at_rt: G, +) -> RET +where + F: const FnOnce, + G: FnOnce, +{ + loop {} } fn test_const_eval_select() { From e0d67aeb0b5aea49136548c34c369fe0c8391ddf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 17:47:57 +0000 Subject: [PATCH 2/5] Make `vtable_align` a rustc_intrinsic --- library/core/src/intrinsics.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 9a7ade8a83727..027a0e8effdb6 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2506,6 +2506,7 @@ extern "rust-intrinsic" { /// `ptr` must point to a vtable. /// The intrinsic will return the alignment stored in that vtable. #[rustc_nounwind] + #[cfg(bootstrap)] pub fn vtable_align(ptr: *const ()) -> usize; #[cfg(bootstrap)] @@ -2720,13 +2721,24 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) /// The intrinsic will return the size stored in that vtable. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_must_be_overridden)] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] #[cfg(not(bootstrap))] pub unsafe fn vtable_size(_ptr: *const ()) -> usize { unreachable!() } +/// `ptr` must point to a vtable. +/// The intrinsic will return the alignment stored in that vtable. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub unsafe fn vtable_align(_ptr: *const ()) -> usize { + unreachable!() +} + // Some functions are defined here because they accidentally got made // available in this module on stable. See . // (`transmute` also falls into this category, but it cannot be wrapped due to the From 3e5c468662d0137665a4381ad85912a763c7a3ef Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 17:50:07 +0000 Subject: [PATCH 3/5] Make ptr_guaranteed_cmp a rustc_intrinsic and favor its body over backends implementing it --- .../src/intrinsics/mod.rs | 7 ----- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 7 ----- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- library/core/src/intrinsics.rs | 27 ++++++++++++------- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index c802d9bbefbed..25694af78f17e 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -757,13 +757,6 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, val); } - sym::ptr_guaranteed_cmp => { - intrinsic_args!(fx, args => (a, b); intrinsic); - - let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b).load_scalar(fx); - ret.write_cvalue(fx, CValue::by_val(val, fx.layout_of(fx.tcx.types.u8))); - } - sym::caller_location => { intrinsic_args!(fx, args => (); intrinsic); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index ba023f96107a4..5532ff6e6a5d7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,7 +1,6 @@ use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; use super::FunctionCx; -use crate::common::IntPredicate; use crate::errors; use crate::errors::InvalidMonomorphization; use crate::meth; @@ -456,12 +455,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return Ok(()); } - sym::ptr_guaranteed_cmp => { - let a = args[0].immediate(); - let b = args[1].immediate(); - bx.icmp(IntPredicate::IntEQ, a, b) - } - sym::ptr_offset_from | sym::ptr_offset_from_unsigned => { let ty = fn_args.type_at(0); let pointee_size = bx.layout_of(ty).size; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 7a1fe3b1cdc4d..07054c184f401 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -441,7 +441,7 @@ pub fn check_intrinsic_type( sym::ptr_guaranteed_cmp => ( 1, - 0, + 1, vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))], tcx.types.u8, ), diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 027a0e8effdb6..66e55a5e217d6 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2434,20 +2434,29 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn ptr_offset_from_unsigned(ptr: *const T, base: *const T) -> usize; - /// See documentation of `<*const T>::guaranteed_eq` for details. - /// Returns `2` if the result is unknown. - /// Returns `1` if the pointers are guaranteed equal - /// Returns `0` if the pointers are guaranteed inequal - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[rustc_safe_intrinsic] #[rustc_nounwind] + #[cfg(bootstrap)] pub fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8; +} +/// See documentation of `<*const T>::guaranteed_eq` for details. +/// Returns `2` if the result is unknown. +/// Returns `1` if the pointers are guaranteed equal +/// Returns `0` if the pointers are guaranteed inequal +#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_intrinsic] +#[cfg(not(bootstrap))] +#[rustc_nounwind] +#[rustc_do_not_const_check] +#[inline] +pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { + (ptr == other) as u8 +} + +extern "rust-intrinsic" { /// Determines whether the raw bytes of the two values are equal. /// /// This is particularly handy for arrays, since it allows things like just From e91084180e2171fd229241adfb4b1463ebb79958 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 Mar 2024 13:49:50 +0000 Subject: [PATCH 4/5] Make span_bug panic site useful again --- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/ty/context/tls.rs | 7 ++++++- compiler/rustc_middle/src/util/bug.rs | 19 +++++++++++-------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index e47668b9110ff..d910a15e26202 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -31,6 +31,7 @@ #![feature(array_windows)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(closure_track_caller)] #![feature(core_intrinsics)] #![feature(const_type_name)] #![feature(discriminant_kind)] diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index 788ccd5dbbdc7..5e256dc8d26e2 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -85,6 +85,7 @@ where /// Allows access to the current `ImplicitCtxt` in a closure if one is available. #[inline] +#[track_caller] pub fn with_context_opt(f: F) -> R where F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R, @@ -147,9 +148,13 @@ where /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`. /// The closure is passed None if there is no `ImplicitCtxt` available. #[inline] +#[track_caller] pub fn with_opt(f: F) -> R where F: for<'tcx> FnOnce(Option>) -> R, { - with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx))) + with_context_opt( + #[track_caller] + |opt_context| f(opt_context.map(|context| context.tcx)), + ) } diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index a67ec99158210..43853a108960f 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -28,14 +28,17 @@ fn opt_span_bug_fmt>( args: fmt::Arguments<'_>, location: &Location<'_>, ) -> ! { - tls::with_opt(move |tcx| { - let msg = format!("{location}: {args}"); - match (tcx, span) { - (Some(tcx), Some(span)) => tcx.dcx().span_bug(span, msg), - (Some(tcx), None) => tcx.dcx().bug(msg), - (None, _) => panic_any(msg), - } - }) + tls::with_opt( + #[track_caller] + move |tcx| { + let msg = format!("{location}: {args}"); + match (tcx, span) { + (Some(tcx), Some(span)) => tcx.dcx().span_bug(span, msg), + (Some(tcx), None) => tcx.dcx().bug(msg), + (None, _) => panic_any(msg), + } + }, + ) } /// A query to trigger a delayed bug. Clearly, if one has a `tcx` one can already trigger a From a8f71cf2893e03ec0ef7663f680f5d816e80f801 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 12 Mar 2024 16:04:52 +0000 Subject: [PATCH 5/5] Remove all checks of `IntrinsicDef::must_be_overridden` except for the actual overrides in codegen --- compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 4 ---- compiler/rustc_metadata/src/rmeta/encoder.rs | 11 +++-------- compiler/rustc_middle/src/hir/map/mod.rs | 4 +--- compiler/rustc_mir_build/src/build/mod.rs | 9 +++++++-- .../rustc_mir_transform/src/cross_crate_inline.rs | 4 ---- compiler/rustc_mir_transform/src/lib.rs | 6 ------ compiler/rustc_monomorphize/src/collector.rs | 5 ----- 7 files changed, 11 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 87b6f0e914c35..b19f52182b650 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -81,10 +81,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap {} diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 68911f579cd93..0a9659745dbf4 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1067,14 +1067,11 @@ fn should_encode_mir( // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { let generics = tcx.generics_of(def_id); - let mut opt = tcx.sess.opts.unstable_opts.always_encode_mir + let 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 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()); @@ -1704,10 +1701,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { for &local_def_id in tcx.mir_keys(()) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { - if tcx.intrinsic(local_def_id).map_or(true, |i| !i.must_be_overridden) { - record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- - self.tcx.deduced_param_attrs(local_def_id.to_def_id())); - } + record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- + self.tcx.deduced_param_attrs(local_def_id.to_def_id())); } } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 57a88a0310919..5043bd855ccb9 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1365,9 +1365,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { if associated_body(Node::ImplItem(item)).is_some() { - if !self.tcx.has_attr(item.owner_id.def_id, sym::rustc_intrinsic_must_be_overridden) { - self.body_owners.push(item.owner_id.def_id); - } + self.body_owners.push(item.owner_id.def_id); } self.impl_items.push(item.impl_item_id()); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 411119b521bcd..acadfe7b35eb7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1013,8 +1013,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let Some(source_scope) = scope { self.source_scope = source_scope; } - - self.expr_into_dest(Place::return_place(), block, expr_id) + if self.tcx.intrinsic(self.def_id).is_some_and(|i| i.must_be_overridden) { + let source_info = self.source_info(rustc_span::DUMMY_SP); + self.cfg.terminate(block, source_info, TerminatorKind::Unreachable); + self.cfg.start_new_block().unit() + } else { + self.expr_into_dest(Place::return_place(), block, expr_id) + } } fn set_correct_source_scope_for_arg( diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 07e6ecccaa42c..483fd753e7077 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -23,10 +23,6 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return false; } - if tcx.intrinsic(def_id).is_some_and(|i| i.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 afe228be12797..c63bdff9a85b0 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -633,12 +633,6 @@ fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> { } fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { - if tcx.intrinsic(did).is_some_and(|i| i.must_be_overridden) { - span_bug!( - tcx.def_span(did), - "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 d8bdbd8c442b0..abe691ba0d83d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1030,11 +1030,6 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> return false; } - if tcx.intrinsic(def_id).is_some_and(|i| i.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;