diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 6af75bc94bb63..2753ac529d12d 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -273,8 +273,7 @@ pub fn find_stability(
 /// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
 /// attributes in `attrs`. Returns `None` if no stability attributes are found.
 ///
-/// `is_const_fn` indicates whether this is a function marked as `const`. It will always
-/// be false for intrinsics in an `extern` block!
+/// `is_const_fn` indicates whether this is a function marked as `const`.
 pub fn find_const_stability(
     sess: &Session,
     attrs: &[Attribute],
@@ -330,7 +329,7 @@ pub fn find_const_stability(
         }
     }
 
-    // Merge promotable and not_exposed_on_stable into stability info
+    // Merge promotable and const_stable_indirect into stability info
     if promotable {
         match &mut const_stab {
             Some((stab, _)) => stab.promotable = promotable,
@@ -352,10 +351,7 @@ pub fn find_const_stability(
                     })
                 }
             }
-            _ => {
-                // We ignore the `#[rustc_const_stable_indirect]` here, it should be picked up by
-                // the `default_const_unstable` logic.
-            }
+            _ => {}
         }
     }
     // Make sure if `const_stable_indirect` is present, that is recorded. Also make sure all `const
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 2bc5adb2dce60..826e34930eae7 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -399,7 +399,7 @@ const_eval_uninhabited_enum_variant_written =
 const_eval_unmarked_const_fn_exposed = `{$def_path}` cannot be (indirectly) exposed to stable
     .help = either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
 const_eval_unmarked_intrinsic_exposed = intrinsic `{$def_path}` cannot be (indirectly) exposed to stable
-    .help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_indirect]` (but this requires team approval)
+    .help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
 
 const_eval_unreachable = entering unreachable code
 const_eval_unreachable_unwind =
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 8cb7e02036fd8..aea3d5bd3e70f 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -736,16 +736,25 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                 // Intrinsics are language primitives, not regular calls, so treat them separately.
                 if let Some(intrinsic) = tcx.intrinsic(callee) {
+                    // We use `intrinsic.const_stable` to determine if this can be safely exposed to
+                    // stable code, rather than `const_stable_indirect`. This is to make
+                    // `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
+                    // We also ask is_safe_to_expose_on_stable_const_fn; this determines whether the intrinsic
+                    // fallback body is safe to expose on stable.
+                    let is_const_stable = intrinsic.const_stable
+                        || (!intrinsic.must_be_overridden
+                            && tcx.is_const_fn(callee)
+                            && is_safe_to_expose_on_stable_const_fn(tcx, callee));
                     match tcx.lookup_const_stability(callee) {
                         None => {
                             // Non-const intrinsic.
                             self.check_op(ops::IntrinsicNonConst { name: intrinsic.name });
                         }
-                        Some(ConstStability { feature: None, const_stable_indirect, .. }) => {
+                        Some(ConstStability { feature: None, .. }) => {
                             // Intrinsic does not need a separate feature gate (we rely on the
                             // regular stability checker). However, we have to worry about recursive
                             // const stability.
-                            if !const_stable_indirect && self.enforce_recursive_const_stability() {
+                            if !is_const_stable && self.enforce_recursive_const_stability() {
                                 self.dcx().emit_err(errors::UnmarkedIntrinsicExposed {
                                     span: self.span,
                                     def_path: self.tcx.def_path_str(callee),
@@ -755,17 +764,19 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                         Some(ConstStability {
                             feature: Some(feature),
                             level: StabilityLevel::Unstable { .. },
-                            const_stable_indirect,
                             ..
                         }) => {
                             self.check_op(ops::IntrinsicUnstable {
                                 name: intrinsic.name,
                                 feature,
-                                const_stable_indirect,
+                                const_stable: is_const_stable,
                             });
                         }
                         Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
-                            // All good.
+                            // All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
+                            // can be *directly* invoked from stable const code) does not always
+                            // have the `#[rustc_const_stable_intrinsic]` attribute (which controls
+                            // exposing an intrinsic indirectly); we accept this call anyway.
                         }
                     }
                     // This completes the checks for intrinsics.
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index d264cab1511b9..2931159842f95 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -354,14 +354,14 @@ impl<'tcx> NonConstOp<'tcx> for IntrinsicNonConst {
 pub(crate) struct IntrinsicUnstable {
     pub name: Symbol,
     pub feature: Symbol,
-    pub const_stable_indirect: bool,
+    pub const_stable: bool,
 }
 
 impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
     fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
         Status::Unstable {
             gate: self.feature,
-            safe_to_expose_on_stable: self.const_stable_indirect,
+            safe_to_expose_on_stable: self.const_stable,
             // We do *not* want to suggest to mark the intrinsic as `const_stable_indirect`,
             // that's not a trivial change!
             is_function_call: false,
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 037fdcbcf9b4c..beff0cd99fc47 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -25,15 +25,9 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
             hir::Constness::Const
         }
         hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
-        hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
-            // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
-            // foreign items cannot be evaluated at compile-time.
-            let is_const = if tcx.intrinsic(def_id).is_some() {
-                tcx.lookup_const_stability(def_id).is_some()
-            } else {
-                false
-            };
-            if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
+        hir::Node::ForeignItem(_) => {
+            // Foreign items cannot be evaluated at compile-time.
+            hir::Constness::NotConst
         }
         hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
         _ => {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 0069b07ad6259..cc0bdec701929 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -837,6 +837,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_const_stable_indirect, Normal,
         template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
     ),
+    rustc_attr!(
+        rustc_const_stable_intrinsic, Normal,
+        template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
+    ),
     gated!(
         rustc_allow_const_fn_unstable, Normal,
         template!(Word, List: "feat1, feat2, ..."), DuplicatesOk, EncodeCrossCrate::No,
diff --git a/compiler/rustc_middle/src/ty/intrinsic.rs b/compiler/rustc_middle/src/ty/intrinsic.rs
index ed0fb37d3b897..6a3ddacb424e8 100644
--- a/compiler/rustc_middle/src/ty/intrinsic.rs
+++ b/compiler/rustc_middle/src/ty/intrinsic.rs
@@ -9,6 +9,8 @@ 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,
+    /// Whether the intrinsic can be invoked from stable const fn
+    pub const_stable: bool,
 }
 
 impl TyCtxt<'_> {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 83276808a28e6..6ffd149ef1475 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1789,6 +1789,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
         Some(ty::IntrinsicDef {
             name: tcx.item_name(def_id.into()),
             must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
+            const_stable: tcx.has_attr(def_id, sym::rustc_const_stable_intrinsic),
         })
     } else {
         None
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 737e163efcef1..cd47c8ece6015 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -106,7 +106,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         def_id: LocalDefId,
         item_sp: Span,
         fn_sig: Option<&'tcx hir::FnSig<'tcx>>,
-        is_foreign_item: bool,
         kind: AnnotationKind,
         inherit_deprecation: InheritDeprecation,
         inherit_const_stability: InheritConstStability,
@@ -175,11 +174,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         // implied), check if the function/method is const or the parent impl block is const.
         if let Some(fn_sig) = fn_sig
             && !fn_sig.header.is_const()
-            // We have to exclude foreign items as they might be intrinsics. Sadly we can't check
-            // their ABI; `fn_sig.abi` is *not* correct for foreign functions.
-            && !is_foreign_item
             && const_stab.is_some()
-            && (!self.in_trait_impl || !self.tcx.is_const_fn(def_id.to_def_id()))
         {
             self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span });
         }
@@ -398,7 +393,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                         ctor_def_id,
                         i.span,
                         None,
-                        /* is_foreign_item */ false,
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
                         InheritConstStability::No,
@@ -417,7 +411,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             i.owner_id.def_id,
             i.span,
             fn_sig,
-            /* is_foreign_item */ false,
             kind,
             InheritDeprecation::Yes,
             const_stab_inherit,
@@ -437,7 +430,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             ti.owner_id.def_id,
             ti.span,
             fn_sig,
-            /* is_foreign_item */ false,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
@@ -461,7 +453,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             ii.owner_id.def_id,
             ii.span,
             fn_sig,
-            /* is_foreign_item */ false,
             kind,
             InheritDeprecation::Yes,
             InheritConstStability::No,
@@ -477,7 +468,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             var.def_id,
             var.span,
             None,
-            /* is_foreign_item */ false,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
@@ -488,7 +478,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                         ctor_def_id,
                         var.span,
                         None,
-                        /* is_foreign_item */ false,
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
                         InheritConstStability::No,
@@ -507,7 +496,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             s.def_id,
             s.span,
             None,
-            /* is_foreign_item */ false,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
@@ -527,7 +515,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             i.owner_id.def_id,
             i.span,
             fn_sig,
-            /* is_foreign_item */ true,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
@@ -550,7 +537,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             p.def_id,
             p.span,
             None,
-            /* is_foreign_item */ false,
             kind,
             InheritDeprecation::No,
             InheritConstStability::No,
@@ -712,7 +698,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
             CRATE_DEF_ID,
             tcx.hir().span(CRATE_HIR_ID),
             None,
-            /* is_foreign_item */ false,
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index fac2180d63b47..21a74bd4020ac 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1663,6 +1663,7 @@ symbols! {
         rustc_const_panic_str,
         rustc_const_stable,
         rustc_const_stable_indirect,
+        rustc_const_stable_intrinsic,
         rustc_const_unstable,
         rustc_conversion_suggestion,
         rustc_deallocator,
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index fc09da7bcbc65..c0d4a1eb34dcb 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -8,16 +8,16 @@
 //! Note: any changes to the constness of intrinsics should be discussed with the language team.
 //! This includes changes in the stability of the constness.
 //!
-//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
-//! from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics> to
-//! <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs> and add a
-//! `#[rustc_const_unstable(feature = "const_such_and_such", issue = "01234")]` to the intrinsic declaration.
+//! In order to make an intrinsic usable at compile-time, it needs to be declared in the "new"
+//! style, i.e. as a `#[rustc_intrinsic]` function, not inside an `extern` block. Then copy the
+//! implementation from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics> to
+//! <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs>
+//! and make the intrinsic declaration a `const fn`.
 //!
 //! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
-//! `#[rustc_const_stable_indirect]` needs to be added to the intrinsic (`#[rustc_const_unstable]`
-//! can be removed then). Such a change should not be done without T-lang consultation, because it
-//! may bake a feature into the language that cannot be replicated in user code without compiler
-//! support.
+//! `#[rustc_const_stable_intrinsic]` needs to be added to the intrinsic. Such a change requires
+//! T-lang approval, because it may bake a feature into the language that cannot be replicated in
+//! user code without compiler support.
 //!
 //! # Volatiles
 //!
@@ -936,21 +936,31 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn abort() -> !;
 
-    /// Informs the optimizer that this point in the code is not reachable,
-    /// enabling further optimizations.
-    ///
-    /// N.B., this is very different from the `unreachable!()` macro: Unlike the
-    /// macro, which panics when it is executed, it is *undefined behavior* to
-    /// reach code marked with this function.
+    /// Executes a breakpoint trap, for inspection by a debugger.
     ///
-    /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`].
-    #[cfg_attr(
-        bootstrap,
-        rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")
-    )]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+    /// This intrinsic does not have a stable counterpart.
     #[rustc_nounwind]
-    pub fn unreachable() -> !;
+    pub fn breakpoint();
+}
+
+/// Informs the optimizer that this point in the code is not reachable,
+/// enabling further optimizations.
+///
+/// N.B., this is very different from the `unreachable!()` macro: Unlike the
+/// macro, which panics when it is executed, it is *undefined behavior* to
+/// reach code marked with this function.
+///
+/// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`].
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")
+)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unreachable() -> ! {
+    unreachable!()
 }
 
 /// Informs the optimizer that a condition is always true.
@@ -964,7 +974,7 @@ extern "rust-intrinsic" {
 ///
 /// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`].
 #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assume", since = "1.77.0"))]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
@@ -990,7 +1000,7 @@ pub const unsafe fn assume(b: bool) {
     bootstrap,
     rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION")
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
 #[rustc_nounwind]
@@ -1014,7 +1024,7 @@ pub const fn likely(b: bool) -> bool {
     bootstrap,
     rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION")
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
 #[rustc_nounwind]
@@ -1044,437 +1054,465 @@ pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
     if b { true_val } else { false_val }
 }
 
-extern "rust-intrinsic" {
-    /// Executes a breakpoint trap, for inspection by a debugger.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    pub fn breakpoint();
+/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
+/// This will statically either panic, or do nothing.
+///
+/// This intrinsic does not have a stable counterpart.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type", since = "1.59.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn assert_inhabited<T>() {
+    unreachable!()
+}
 
-    /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
-    /// This will statically either panic, or do nothing.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type", since = "1.59.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn assert_inhabited<T>();
+/// A guard for unsafe functions that cannot ever be executed if `T` does not permit
+/// zero-initialization: This will statically either panic, or do nothing.
+///
+/// This intrinsic does not have a stable counterpart.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn assert_zero_valid<T>() {
+    unreachable!()
+}
 
-    /// A guard for unsafe functions that cannot ever be executed if `T` does not permit
-    /// zero-initialization: This will statically either panic, or do nothing.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn assert_zero_valid<T>();
+/// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing.
+///
+/// This intrinsic does not have a stable counterpart.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn assert_mem_uninitialized_valid<T>() {
+    unreachable!()
+}
 
-    /// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn assert_mem_uninitialized_valid<T>();
+/// Gets a reference to a static `Location` indicating where it was called.
+///
+/// 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.
+///
+/// Consider using [`core::panic::Location::caller`] instead.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_caller_location", since = "1.79.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn caller_location() -> &'static crate::panic::Location<'static> {
+    unreachable!()
+}
 
-    /// Gets a reference to a static `Location` indicating where it was called.
-    ///
-    /// 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.
-    ///
-    /// Consider using [`core::panic::Location::caller`] instead.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_caller_location", since = "1.79.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn caller_location() -> &'static crate::panic::Location<'static>;
+/// Moves a value out of scope without running drop glue.
+///
+/// This exists solely for [`crate::mem::forget_unsized`]; normal `forget` uses
+/// `ManuallyDrop` instead.
+///
+/// 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.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_forget", since = "1.83.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn forget<T: ?Sized>(_: T) {
+    unreachable!()
+}
 
-    /// Moves a value out of scope without running drop glue.
-    ///
-    /// This exists solely for [`crate::mem::forget_unsized`]; normal `forget` uses
-    /// `ManuallyDrop` instead.
-    ///
-    /// 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.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_forget", since = "1.83.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn forget<T: ?Sized>(_: T);
-
-    /// Reinterprets the bits of a value of one type as another type.
-    ///
-    /// Both types must have the same size. Compilation will fail if this is not guaranteed.
-    ///
-    /// `transmute` is semantically equivalent to a bitwise move of one type
-    /// into another. It copies the bits from the source value into the
-    /// destination value, then forgets the original. Note that source and destination
-    /// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
-    /// is *not* guaranteed to be preserved by `transmute`.
-    ///
-    /// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
-    /// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
-    /// will generate code *assuming that you, the programmer, ensure that there will never be
-    /// undefined behavior*. It is therefore your responsibility to guarantee that every value
-    /// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
-    /// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
-    /// unsafe**. `transmute` should be the absolute last resort.
-    ///
-    /// Because `transmute` is a by-value operation, alignment of the *transmuted values
-    /// themselves* is not a concern. As with any other function, the compiler already ensures
-    /// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
-    /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
-    /// alignment of the pointed-to values.
-    ///
-    /// The [nomicon](../../nomicon/transmutes.html) has additional documentation.
-    ///
-    /// [ub]: ../../reference/behavior-considered-undefined.html
-    ///
-    /// # Transmutation between pointers and integers
-    ///
-    /// Special care has to be taken when transmuting between pointers and integers, e.g.
-    /// transmuting between `*const ()` and `usize`.
-    ///
-    /// Transmuting *pointers to integers* in a `const` context is [undefined behavior][ub], unless
-    /// the pointer was originally created *from* an integer. (That includes this function
-    /// specifically, integer-to-pointer casts, and helpers like [`dangling`][crate::ptr::dangling],
-    /// but also semantically-equivalent conversions such as punning through `repr(C)` union
-    /// fields.) Any attempt to use the resulting value for integer operations will abort
-    /// const-evaluation. (And even outside `const`, such transmutation is touching on many
-    /// unspecified aspects of the Rust memory model and should be avoided. See below for
-    /// alternatives.)
-    ///
-    /// Transmuting *integers to pointers* is a largely unspecified operation. It is likely *not*
-    /// equivalent to an `as` cast. Doing non-zero-sized memory accesses with a pointer constructed
-    /// this way is currently considered undefined behavior.
-    ///
-    /// All this also applies when the integer is nested inside an array, tuple, struct, or enum.
-    /// However, `MaybeUninit<usize>` is not considered an integer type for the purpose of this
-    /// section. Transmuting `*const ()` to `MaybeUninit<usize>` is fine---but then calling
-    /// `assume_init()` on that result is considered as completing the pointer-to-integer transmute
-    /// and thus runs into the issues discussed above.
-    ///
-    /// In particular, doing a pointer-to-integer-to-pointer roundtrip via `transmute` is *not* a
-    /// lossless process. If you want to round-trip a pointer through an integer in a way that you
-    /// can get back the original pointer, you need to use `as` casts, or replace the integer type
-    /// by `MaybeUninit<$int>` (and never call `assume_init()`). If you are looking for a way to
-    /// store data of arbitrary type, also use `MaybeUninit<T>` (that will also handle uninitialized
-    /// memory due to padding). If you specifically need to store something that is "either an
-    /// integer or a pointer", use `*mut ()`: integers can be converted to pointers and back without
-    /// any loss (via `as` casts or via `transmute`).
-    ///
-    /// # Examples
-    ///
-    /// There are a few things that `transmute` is really useful for.
-    ///
-    /// Turning a pointer into a function pointer. This is *not* portable to
-    /// machines where function pointers and data pointers have different sizes.
-    ///
-    /// ```
-    /// fn foo() -> i32 {
-    ///     0
-    /// }
-    /// // Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
-    /// // This avoids an integer-to-pointer `transmute`, which can be problematic.
-    /// // Transmuting between raw pointers and function pointers (i.e., two pointer types) is fine.
-    /// let pointer = foo as *const ();
-    /// let function = unsafe {
-    ///     std::mem::transmute::<*const (), fn() -> i32>(pointer)
-    /// };
-    /// assert_eq!(function(), 0);
-    /// ```
-    ///
-    /// Extending a lifetime, or shortening an invariant lifetime. This is
-    /// advanced, very unsafe Rust!
-    ///
-    /// ```
-    /// struct R<'a>(&'a i32);
-    /// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
-    ///     std::mem::transmute::<R<'b>, R<'static>>(r)
-    /// }
-    ///
-    /// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
-    ///                                              -> &'b mut R<'c> {
-    ///     std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
-    /// }
-    /// ```
-    ///
-    /// # Alternatives
-    ///
-    /// Don't despair: many uses of `transmute` can be achieved through other means.
-    /// Below are common applications of `transmute` which can be replaced with safer
-    /// constructs.
-    ///
-    /// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
-    ///
-    /// ```
-    /// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
-    ///
-    /// let num = unsafe {
-    ///     std::mem::transmute::<[u8; 4], u32>(raw_bytes)
-    /// };
-    ///
-    /// // use `u32::from_ne_bytes` instead
-    /// let num = u32::from_ne_bytes(raw_bytes);
-    /// // or use `u32::from_le_bytes` or `u32::from_be_bytes` to specify the endianness
-    /// let num = u32::from_le_bytes(raw_bytes);
-    /// assert_eq!(num, 0x12345678);
-    /// let num = u32::from_be_bytes(raw_bytes);
-    /// assert_eq!(num, 0x78563412);
-    /// ```
-    ///
-    /// Turning a pointer into a `usize`:
-    ///
-    /// ```no_run
-    /// let ptr = &0;
-    /// let ptr_num_transmute = unsafe {
-    ///     std::mem::transmute::<&i32, usize>(ptr)
-    /// };
-    ///
-    /// // Use an `as` cast instead
-    /// let ptr_num_cast = ptr as *const i32 as usize;
-    /// ```
-    ///
-    /// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
-    /// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
-    /// as expected -- this is touching on many unspecified aspects of the Rust memory model.
-    /// Depending on what the code is doing, the following alternatives are preferable to
-    /// pointer-to-integer transmutation:
-    /// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
-    ///   type for that buffer, it can use [`MaybeUninit`][crate::mem::MaybeUninit].
-    /// - If the code actually wants to work on the address the pointer points to, it can use `as`
-    ///   casts or [`ptr.addr()`][pointer::addr].
-    ///
-    /// Turning a `*mut T` into a `&mut T`:
-    ///
-    /// ```
-    /// let ptr: *mut i32 = &mut 0;
-    /// let ref_transmuted = unsafe {
-    ///     std::mem::transmute::<*mut i32, &mut i32>(ptr)
-    /// };
-    ///
-    /// // Use a reborrow instead
-    /// let ref_casted = unsafe { &mut *ptr };
-    /// ```
-    ///
-    /// Turning a `&mut T` into a `&mut U`:
-    ///
-    /// ```
-    /// let ptr = &mut 0;
-    /// let val_transmuted = unsafe {
-    ///     std::mem::transmute::<&mut i32, &mut u32>(ptr)
-    /// };
-    ///
-    /// // Now, put together `as` and reborrowing - note the chaining of `as`
-    /// // `as` is not transitive
-    /// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
-    /// ```
-    ///
-    /// Turning a `&str` into a `&[u8]`:
-    ///
-    /// ```
-    /// // this is not a good way to do this.
-    /// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
-    /// assert_eq!(slice, &[82, 117, 115, 116]);
-    ///
-    /// // You could use `str::as_bytes`
-    /// let slice = "Rust".as_bytes();
-    /// assert_eq!(slice, &[82, 117, 115, 116]);
-    ///
-    /// // Or, just use a byte string, if you have control over the string
-    /// // literal
-    /// assert_eq!(b"Rust", &[82, 117, 115, 116]);
-    /// ```
-    ///
-    /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`.
-    ///
-    /// To transmute the inner type of the contents of a container, you must make sure to not
-    /// violate any of the container's invariants. For `Vec`, this means that both the size
-    /// *and alignment* of the inner types have to match. Other containers might rely on the
-    /// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't
-    /// be possible at all without violating the container invariants.
-    ///
-    /// ```
-    /// let store = [0, 1, 2, 3];
-    /// let v_orig = store.iter().collect::<Vec<&i32>>();
-    ///
-    /// // clone the vector as we will reuse them later
-    /// let v_clone = v_orig.clone();
-    ///
-    /// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a
-    /// // bad idea and could cause Undefined Behavior.
-    /// // However, it is no-copy.
-    /// let v_transmuted = unsafe {
-    ///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
-    /// };
-    ///
-    /// let v_clone = v_orig.clone();
-    ///
-    /// // This is the suggested, safe way.
-    /// // It may copy the entire vector into a new one though, but also may not.
-    /// let v_collected = v_clone.into_iter()
-    ///                          .map(Some)
-    ///                          .collect::<Vec<Option<&i32>>>();
-    ///
-    /// let v_clone = v_orig.clone();
-    ///
-    /// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
-    /// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
-    /// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
-    /// // this has all the same caveats. Besides the information provided above, also consult the
-    /// // [`from_raw_parts`] documentation.
-    /// let v_from_raw = unsafe {
-    // FIXME Update this when vec_into_raw_parts is stabilized
-    ///     // Ensure the original vector is not dropped.
-    ///     let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
-    ///     Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
-    ///                         v_clone.len(),
-    ///                         v_clone.capacity())
-    /// };
-    /// ```
-    ///
-    /// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts
-    ///
-    /// Implementing `split_at_mut`:
-    ///
-    /// ```
-    /// use std::{slice, mem};
-    ///
-    /// // There are multiple ways to do this, and there are multiple problems
-    /// // with the following (transmute) way.
-    /// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
-    ///                              -> (&mut [T], &mut [T]) {
-    ///     let len = slice.len();
-    ///     assert!(mid <= len);
-    ///     unsafe {
-    ///         let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
-    ///         // first: transmute is not type safe; all it checks is that T and
-    ///         // U are of the same size. Second, right here, you have two
-    ///         // mutable references pointing to the same memory.
-    ///         (&mut slice[0..mid], &mut slice2[mid..len])
-    ///     }
-    /// }
-    ///
-    /// // This gets rid of the type safety problems; `&mut *` will *only* give
-    /// // you a `&mut T` from a `&mut T` or `*mut T`.
-    /// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
-    ///                          -> (&mut [T], &mut [T]) {
-    ///     let len = slice.len();
-    ///     assert!(mid <= len);
-    ///     unsafe {
-    ///         let slice2 = &mut *(slice as *mut [T]);
-    ///         // however, you still have two mutable references pointing to
-    ///         // the same memory.
-    ///         (&mut slice[0..mid], &mut slice2[mid..len])
-    ///     }
-    /// }
-    ///
-    /// // This is how the standard library does it. This is the best method, if
-    /// // you need to do something like this
-    /// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
-    ///                       -> (&mut [T], &mut [T]) {
-    ///     let len = slice.len();
-    ///     assert!(mid <= len);
-    ///     unsafe {
-    ///         let ptr = slice.as_mut_ptr();
-    ///         // This now has three mutable references pointing at the same
-    ///         // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
-    ///         // `slice` is never used after `let ptr = ...`, and so one can
-    ///         // treat it as "dead", and therefore, you only have two real
-    ///         // mutable slices.
-    ///         (slice::from_raw_parts_mut(ptr, mid),
-    ///          slice::from_raw_parts_mut(ptr.add(mid), len - mid))
-    ///     }
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_allowed_through_unstable_modules]
-    #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
-    #[rustc_diagnostic_item = "transmute"]
-    #[rustc_nounwind]
-    pub fn transmute<Src, Dst>(src: Src) -> Dst;
-
-    /// Like [`transmute`], but even less checked at compile-time: rather than
-    /// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's
-    /// **Undefined Behavior** at runtime.
-    ///
-    /// Prefer normal `transmute` where possible, for the extra checking, since
-    /// both do exactly the same thing at runtime, if they both compile.
-    ///
-    /// This is not expected to ever be exposed directly to users, rather it
-    /// may eventually be exposed through some more-constrained API.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_transmute", since = "1.56.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
-
-    /// Returns `true` if the actual type given as `T` requires drop
-    /// glue; returns `false` if the actual type provided for `T`
-    /// implements `Copy`.
-    ///
-    /// If the actual type neither requires drop glue nor implements
-    /// `Copy`, then the return value of this function is unspecified.
-    ///
-    /// 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.
-    ///
-    /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_needs_drop", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn needs_drop<T: ?Sized>() -> bool;
+/// Reinterprets the bits of a value of one type as another type.
+///
+/// Both types must have the same size. Compilation will fail if this is not guaranteed.
+///
+/// `transmute` is semantically equivalent to a bitwise move of one type
+/// into another. It copies the bits from the source value into the
+/// destination value, then forgets the original. Note that source and destination
+/// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
+/// is *not* guaranteed to be preserved by `transmute`.
+///
+/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
+/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
+/// will generate code *assuming that you, the programmer, ensure that there will never be
+/// undefined behavior*. It is therefore your responsibility to guarantee that every value
+/// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
+/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
+/// unsafe**. `transmute` should be the absolute last resort.
+///
+/// Because `transmute` is a by-value operation, alignment of the *transmuted values
+/// themselves* is not a concern. As with any other function, the compiler already ensures
+/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
+/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
+/// alignment of the pointed-to values.
+///
+/// The [nomicon](../../nomicon/transmutes.html) has additional documentation.
+///
+/// [ub]: ../../reference/behavior-considered-undefined.html
+///
+/// # Transmutation between pointers and integers
+///
+/// Special care has to be taken when transmuting between pointers and integers, e.g.
+/// transmuting between `*const ()` and `usize`.
+///
+/// Transmuting *pointers to integers* in a `const` context is [undefined behavior][ub], unless
+/// the pointer was originally created *from* an integer. (That includes this function
+/// specifically, integer-to-pointer casts, and helpers like [`dangling`][crate::ptr::dangling],
+/// but also semantically-equivalent conversions such as punning through `repr(C)` union
+/// fields.) Any attempt to use the resulting value for integer operations will abort
+/// const-evaluation. (And even outside `const`, such transmutation is touching on many
+/// unspecified aspects of the Rust memory model and should be avoided. See below for
+/// alternatives.)
+///
+/// Transmuting *integers to pointers* is a largely unspecified operation. It is likely *not*
+/// equivalent to an `as` cast. Doing non-zero-sized memory accesses with a pointer constructed
+/// this way is currently considered undefined behavior.
+///
+/// All this also applies when the integer is nested inside an array, tuple, struct, or enum.
+/// However, `MaybeUninit<usize>` is not considered an integer type for the purpose of this
+/// section. Transmuting `*const ()` to `MaybeUninit<usize>` is fine---but then calling
+/// `assume_init()` on that result is considered as completing the pointer-to-integer transmute
+/// and thus runs into the issues discussed above.
+///
+/// In particular, doing a pointer-to-integer-to-pointer roundtrip via `transmute` is *not* a
+/// lossless process. If you want to round-trip a pointer through an integer in a way that you
+/// can get back the original pointer, you need to use `as` casts, or replace the integer type
+/// by `MaybeUninit<$int>` (and never call `assume_init()`). If you are looking for a way to
+/// store data of arbitrary type, also use `MaybeUninit<T>` (that will also handle uninitialized
+/// memory due to padding). If you specifically need to store something that is "either an
+/// integer or a pointer", use `*mut ()`: integers can be converted to pointers and back without
+/// any loss (via `as` casts or via `transmute`).
+///
+/// # Examples
+///
+/// There are a few things that `transmute` is really useful for.
+///
+/// Turning a pointer into a function pointer. This is *not* portable to
+/// machines where function pointers and data pointers have different sizes.
+///
+/// ```
+/// fn foo() -> i32 {
+///     0
+/// }
+/// // Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
+/// // This avoids an integer-to-pointer `transmute`, which can be problematic.
+/// // Transmuting between raw pointers and function pointers (i.e., two pointer types) is fine.
+/// let pointer = foo as *const ();
+/// let function = unsafe {
+///     std::mem::transmute::<*const (), fn() -> i32>(pointer)
+/// };
+/// assert_eq!(function(), 0);
+/// ```
+///
+/// Extending a lifetime, or shortening an invariant lifetime. This is
+/// advanced, very unsafe Rust!
+///
+/// ```
+/// struct R<'a>(&'a i32);
+/// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
+///     std::mem::transmute::<R<'b>, R<'static>>(r)
+/// }
+///
+/// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
+///                                              -> &'b mut R<'c> {
+///     std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
+/// }
+/// ```
+///
+/// # Alternatives
+///
+/// Don't despair: many uses of `transmute` can be achieved through other means.
+/// Below are common applications of `transmute` which can be replaced with safer
+/// constructs.
+///
+/// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
+///
+/// ```
+/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
+///
+/// let num = unsafe {
+///     std::mem::transmute::<[u8; 4], u32>(raw_bytes)
+/// };
+///
+/// // use `u32::from_ne_bytes` instead
+/// let num = u32::from_ne_bytes(raw_bytes);
+/// // or use `u32::from_le_bytes` or `u32::from_be_bytes` to specify the endianness
+/// let num = u32::from_le_bytes(raw_bytes);
+/// assert_eq!(num, 0x12345678);
+/// let num = u32::from_be_bytes(raw_bytes);
+/// assert_eq!(num, 0x78563412);
+/// ```
+///
+/// Turning a pointer into a `usize`:
+///
+/// ```no_run
+/// let ptr = &0;
+/// let ptr_num_transmute = unsafe {
+///     std::mem::transmute::<&i32, usize>(ptr)
+/// };
+///
+/// // Use an `as` cast instead
+/// let ptr_num_cast = ptr as *const i32 as usize;
+/// ```
+///
+/// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
+/// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
+/// as expected -- this is touching on many unspecified aspects of the Rust memory model.
+/// Depending on what the code is doing, the following alternatives are preferable to
+/// pointer-to-integer transmutation:
+/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
+///   type for that buffer, it can use [`MaybeUninit`][crate::mem::MaybeUninit].
+/// - If the code actually wants to work on the address the pointer points to, it can use `as`
+///   casts or [`ptr.addr()`][pointer::addr].
+///
+/// Turning a `*mut T` into a `&mut T`:
+///
+/// ```
+/// let ptr: *mut i32 = &mut 0;
+/// let ref_transmuted = unsafe {
+///     std::mem::transmute::<*mut i32, &mut i32>(ptr)
+/// };
+///
+/// // Use a reborrow instead
+/// let ref_casted = unsafe { &mut *ptr };
+/// ```
+///
+/// Turning a `&mut T` into a `&mut U`:
+///
+/// ```
+/// let ptr = &mut 0;
+/// let val_transmuted = unsafe {
+///     std::mem::transmute::<&mut i32, &mut u32>(ptr)
+/// };
+///
+/// // Now, put together `as` and reborrowing - note the chaining of `as`
+/// // `as` is not transitive
+/// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
+/// ```
+///
+/// Turning a `&str` into a `&[u8]`:
+///
+/// ```
+/// // this is not a good way to do this.
+/// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
+/// assert_eq!(slice, &[82, 117, 115, 116]);
+///
+/// // You could use `str::as_bytes`
+/// let slice = "Rust".as_bytes();
+/// assert_eq!(slice, &[82, 117, 115, 116]);
+///
+/// // Or, just use a byte string, if you have control over the string
+/// // literal
+/// assert_eq!(b"Rust", &[82, 117, 115, 116]);
+/// ```
+///
+/// Turning a `Vec<&T>` into a `Vec<Option<&T>>`.
+///
+/// To transmute the inner type of the contents of a container, you must make sure to not
+/// violate any of the container's invariants. For `Vec`, this means that both the size
+/// *and alignment* of the inner types have to match. Other containers might rely on the
+/// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't
+/// be possible at all without violating the container invariants.
+///
+/// ```
+/// let store = [0, 1, 2, 3];
+/// let v_orig = store.iter().collect::<Vec<&i32>>();
+///
+/// // clone the vector as we will reuse them later
+/// let v_clone = v_orig.clone();
+///
+/// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a
+/// // bad idea and could cause Undefined Behavior.
+/// // However, it is no-copy.
+/// let v_transmuted = unsafe {
+///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
+/// };
+///
+/// let v_clone = v_orig.clone();
+///
+/// // This is the suggested, safe way.
+/// // It may copy the entire vector into a new one though, but also may not.
+/// let v_collected = v_clone.into_iter()
+///                          .map(Some)
+///                          .collect::<Vec<Option<&i32>>>();
+///
+/// let v_clone = v_orig.clone();
+///
+/// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
+/// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
+/// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
+/// // this has all the same caveats. Besides the information provided above, also consult the
+/// // [`from_raw_parts`] documentation.
+/// let v_from_raw = unsafe {
+// FIXME Update this when vec_into_raw_parts is stabilized
+///     // Ensure the original vector is not dropped.
+///     let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
+///     Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
+///                         v_clone.len(),
+///                         v_clone.capacity())
+/// };
+/// ```
+///
+/// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts
+///
+/// Implementing `split_at_mut`:
+///
+/// ```
+/// use std::{slice, mem};
+///
+/// // There are multiple ways to do this, and there are multiple problems
+/// // with the following (transmute) way.
+/// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
+///                              -> (&mut [T], &mut [T]) {
+///     let len = slice.len();
+///     assert!(mid <= len);
+///     unsafe {
+///         let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
+///         // first: transmute is not type safe; all it checks is that T and
+///         // U are of the same size. Second, right here, you have two
+///         // mutable references pointing to the same memory.
+///         (&mut slice[0..mid], &mut slice2[mid..len])
+///     }
+/// }
+///
+/// // This gets rid of the type safety problems; `&mut *` will *only* give
+/// // you a `&mut T` from a `&mut T` or `*mut T`.
+/// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
+///                          -> (&mut [T], &mut [T]) {
+///     let len = slice.len();
+///     assert!(mid <= len);
+///     unsafe {
+///         let slice2 = &mut *(slice as *mut [T]);
+///         // however, you still have two mutable references pointing to
+///         // the same memory.
+///         (&mut slice[0..mid], &mut slice2[mid..len])
+///     }
+/// }
+///
+/// // This is how the standard library does it. This is the best method, if
+/// // you need to do something like this
+/// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
+///                       -> (&mut [T], &mut [T]) {
+///     let len = slice.len();
+///     assert!(mid <= len);
+///     unsafe {
+///         let ptr = slice.as_mut_ptr();
+///         // This now has three mutable references pointing at the same
+///         // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
+///         // `slice` is never used after `let ptr = ...`, and so one can
+///         // treat it as "dead", and therefore, you only have two real
+///         // mutable slices.
+///         (slice::from_raw_parts_mut(ptr, mid),
+///          slice::from_raw_parts_mut(ptr.add(mid), len - mid))
+///     }
+/// }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_allowed_through_unstable_modules]
+#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
+#[rustc_diagnostic_item = "transmute"]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn transmute<Src, Dst>(_src: Src) -> Dst {
+    unreachable!()
+}
 
-    /// Calculates the offset from a pointer.
-    ///
-    /// This is implemented as an intrinsic to avoid converting to and from an
-    /// integer, since the conversion would throw away aliasing information.
-    ///
-    /// This can only be used with `Ptr` as a raw pointer type (`*mut` or `*const`)
-    /// to a `Sized` pointee and with `Delta` as `usize` or `isize`.  Any other
-    /// instantiations may arbitrarily misbehave, and that's *not* a compiler bug.
-    ///
-    /// # Safety
-    ///
-    /// If the computed offset is non-zero, then both the starting and resulting pointer must be
-    /// either in bounds or at the end of an allocated object. If either pointer is out
-    /// of bounds or arithmetic overflow occurs then this operation is undefined behavior.
-    ///
-    /// The stabilized version of this intrinsic is [`pointer::offset`].
-    #[must_use = "returns a new pointer rather than modifying its argument"]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
+/// Like [`transmute`], but even less checked at compile-time: rather than
+/// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's
+/// **Undefined Behavior** at runtime.
+///
+/// Prefer normal `transmute` where possible, for the extra checking, since
+/// both do exactly the same thing at runtime, if they both compile.
+///
+/// This is not expected to ever be exposed directly to users, rather it
+/// may eventually be exposed through some more-constrained API.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_transmute", since = "1.56.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn transmute_unchecked<Src, Dst>(_src: Src) -> Dst {
+    unreachable!()
+}
 
-    /// Calculates the offset from a pointer, potentially wrapping.
-    ///
-    /// This is implemented as an intrinsic to avoid converting to and from an
-    /// integer, since the conversion inhibits certain optimizations.
-    ///
-    /// # Safety
-    ///
-    /// Unlike the `offset` intrinsic, this intrinsic does not restrict the
-    /// resulting pointer to point into or at the end of an allocated
-    /// object, and it wraps with two's complement arithmetic. The resulting
-    /// value is not necessarily valid to be used to actually access memory.
-    ///
-    /// The stabilized version of this intrinsic is [`pointer::wrapping_offset`].
-    #[must_use = "returns a new pointer rather than modifying its argument"]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
+/// Returns `true` if the actual type given as `T` requires drop
+/// glue; returns `false` if the actual type provided for `T`
+/// implements `Copy`.
+///
+/// If the actual type neither requires drop glue nor implements
+/// `Copy`, then the return value of this function is unspecified.
+///
+/// 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.
+///
+/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_needs_drop", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn needs_drop<T: ?Sized>() -> bool {
+    unreachable!()
+}
+
+/// Calculates the offset from a pointer.
+///
+/// This is implemented as an intrinsic to avoid converting to and from an
+/// integer, since the conversion would throw away aliasing information.
+///
+/// This can only be used with `Ptr` as a raw pointer type (`*mut` or `*const`)
+/// to a `Sized` pointee and with `Delta` as `usize` or `isize`.  Any other
+/// instantiations may arbitrarily misbehave, and that's *not* a compiler bug.
+///
+/// # Safety
+///
+/// If the computed offset is non-zero, then both the starting and resulting pointer must be
+/// either in bounds or at the end of an allocated object. If either pointer is out
+/// of bounds or arithmetic overflow occurs then this operation is undefined behavior.
+///
+/// The stabilized version of this intrinsic is [`pointer::offset`].
+#[must_use = "returns a new pointer rather than modifying its argument"]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn offset<Ptr, Delta>(_dst: Ptr, _offset: Delta) -> Ptr {
+    unreachable!()
+}
+
+/// Calculates the offset from a pointer, potentially wrapping.
+///
+/// This is implemented as an intrinsic to avoid converting to and from an
+/// integer, since the conversion inhibits certain optimizations.
+///
+/// # Safety
+///
+/// Unlike the `offset` intrinsic, this intrinsic does not restrict the
+/// resulting pointer to point into or at the end of an allocated
+/// object, and it wraps with two's complement arithmetic. The resulting
+/// value is not necessarily valid to be used to actually access memory.
+///
+/// The stabilized version of this intrinsic is [`pointer::wrapping_offset`].
+#[must_use = "returns a new pointer rather than modifying its argument"]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn arith_offset<T>(_dst: *const T, _offset: isize) -> *const T {
+    unreachable!()
+}
 
+extern "rust-intrinsic" {
     /// Masks out bits of the pointer according to a mask.
     ///
     /// Note that, unlike most intrinsics, this is safe to call;
@@ -2143,474 +2181,569 @@ extern "rust-intrinsic" {
     /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`].
     #[rustc_nounwind]
     pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+}
 
-    /// Returns the number of bits set in an integer type `T`
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `count_ones` method. For example,
-    /// [`u32::count_ones`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctpop", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn ctpop<T: Copy>(x: T) -> u32;
+/// Returns the number of bits set in an integer type `T`
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `count_ones` method. For example,
+/// [`u32::count_ones`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctpop", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn ctpop<T: Copy>(_x: T) -> u32 {
+    unimplemented!()
+}
 
-    /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `leading_zeros` method. For example,
-    /// [`u32::leading_zeros`]
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    ///
-    /// use std::intrinsics::ctlz;
-    ///
-    /// let x = 0b0001_1100_u8;
-    /// let num_leading = ctlz(x);
-    /// assert_eq!(num_leading, 3);
-    /// ```
-    ///
-    /// An `x` with value `0` will return the bit width of `T`.
-    ///
-    /// ```
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    ///
-    /// use std::intrinsics::ctlz;
-    ///
-    /// let x = 0u16;
-    /// let num_leading = ctlz(x);
-    /// assert_eq!(num_leading, 16);
-    /// ```
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctlz", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn ctlz<T: Copy>(x: T) -> u32;
+/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `leading_zeros` method. For example,
+/// [`u32::leading_zeros`]
+///
+/// # Examples
+///
+/// ```
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+///
+/// use std::intrinsics::ctlz;
+///
+/// let x = 0b0001_1100_u8;
+/// let num_leading = ctlz(x);
+/// assert_eq!(num_leading, 3);
+/// ```
+///
+/// An `x` with value `0` will return the bit width of `T`.
+///
+/// ```
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+///
+/// use std::intrinsics::ctlz;
+///
+/// let x = 0u16;
+/// let num_leading = ctlz(x);
+/// assert_eq!(num_leading, 16);
+/// ```
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctlz", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn ctlz<T: Copy>(_x: T) -> u32 {
+    unimplemented!()
+}
 
-    /// Like `ctlz`, but extra-unsafe as it returns `undef` when
-    /// given an `x` with value `0`.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    ///
-    /// use std::intrinsics::ctlz_nonzero;
-    ///
-    /// let x = 0b0001_1100_u8;
-    /// let num_leading = unsafe { ctlz_nonzero(x) };
-    /// assert_eq!(num_leading, 3);
-    /// ```
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "constctlz", since = "1.50.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn ctlz_nonzero<T: Copy>(x: T) -> u32;
+/// Like `ctlz`, but extra-unsafe as it returns `undef` when
+/// given an `x` with value `0`.
+///
+/// This intrinsic does not have a stable counterpart.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+///
+/// use std::intrinsics::ctlz_nonzero;
+///
+/// let x = 0b0001_1100_u8;
+/// let num_leading = unsafe { ctlz_nonzero(x) };
+/// assert_eq!(num_leading, 3);
+/// ```
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "constctlz", since = "1.50.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn ctlz_nonzero<T: Copy>(_x: T) -> u32 {
+    unimplemented!()
+}
 
-    /// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `trailing_zeros` method. For example,
-    /// [`u32::trailing_zeros`]
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    ///
-    /// use std::intrinsics::cttz;
-    ///
-    /// let x = 0b0011_1000_u8;
-    /// let num_trailing = cttz(x);
-    /// assert_eq!(num_trailing, 3);
-    /// ```
-    ///
-    /// An `x` with value `0` will return the bit width of `T`:
-    ///
-    /// ```
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    ///
-    /// use std::intrinsics::cttz;
-    ///
-    /// let x = 0u16;
-    /// let num_trailing = cttz(x);
-    /// assert_eq!(num_trailing, 16);
-    /// ```
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn cttz<T: Copy>(x: T) -> u32;
+/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `trailing_zeros` method. For example,
+/// [`u32::trailing_zeros`]
+///
+/// # Examples
+///
+/// ```
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+///
+/// use std::intrinsics::cttz;
+///
+/// let x = 0b0011_1000_u8;
+/// let num_trailing = cttz(x);
+/// assert_eq!(num_trailing, 3);
+/// ```
+///
+/// An `x` with value `0` will return the bit width of `T`:
+///
+/// ```
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+///
+/// use std::intrinsics::cttz;
+///
+/// let x = 0u16;
+/// let num_trailing = cttz(x);
+/// assert_eq!(num_trailing, 16);
+/// ```
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn cttz<T: Copy>(_x: T) -> u32 {
+    unimplemented!()
+}
 
-    /// Like `cttz`, but extra-unsafe as it returns `undef` when
-    /// given an `x` with value `0`.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(core_intrinsics)]
-    /// # #![allow(internal_features)]
-    ///
-    /// use std::intrinsics::cttz_nonzero;
-    ///
-    /// let x = 0b0011_1000_u8;
-    /// let num_trailing = unsafe { cttz_nonzero(x) };
-    /// assert_eq!(num_trailing, 3);
-    /// ```
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn cttz_nonzero<T: Copy>(x: T) -> u32;
+/// Like `cttz`, but extra-unsafe as it returns `undef` when
+/// given an `x` with value `0`.
+///
+/// This intrinsic does not have a stable counterpart.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+///
+/// use std::intrinsics::cttz_nonzero;
+///
+/// let x = 0b0011_1000_u8;
+/// let num_trailing = unsafe { cttz_nonzero(x) };
+/// assert_eq!(num_trailing, 3);
+/// ```
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn cttz_nonzero<T: Copy>(_x: T) -> u32 {
+    unimplemented!()
+}
 
-    /// Reverses the bytes in an integer type `T`.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `swap_bytes` method. For example,
-    /// [`u32::swap_bytes`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bswap", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn bswap<T: Copy>(x: T) -> T;
+/// Reverses the bytes in an integer type `T`.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `swap_bytes` method. For example,
+/// [`u32::swap_bytes`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bswap", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn bswap<T: Copy>(_x: T) -> T {
+    unimplemented!()
+}
 
-    /// Reverses the bits in an integer type `T`.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `reverse_bits` method. For example,
-    /// [`u32::reverse_bits`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bitreverse", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn bitreverse<T: Copy>(x: T) -> T;
+/// Reverses the bits in an integer type `T`.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `reverse_bits` method. For example,
+/// [`u32::reverse_bits`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bitreverse", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn bitreverse<T: Copy>(_x: T) -> T {
+    unimplemented!()
+}
 
-    /// Does a three-way comparison between the two integer arguments.
-    ///
-    /// This is included as an intrinsic as it's useful to let it be one thing
-    /// in MIR, rather than the multiple checks and switches that make its IR
-    /// large and difficult to optimize.
-    ///
-    /// The stabilized version of this intrinsic is [`Ord::cmp`].
-    #[rustc_const_unstable(feature = "const_three_way_compare", issue = "none")]
-    #[rustc_safe_intrinsic]
-    pub fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> crate::cmp::Ordering;
+/// Does a three-way comparison between the two integer arguments.
+///
+/// This is included as an intrinsic as it's useful to let it be one thing
+/// in MIR, rather than the multiple checks and switches that make its IR
+/// large and difficult to optimize.
+///
+/// The stabilized version of this intrinsic is [`Ord::cmp`].
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_three_way_compare", issue = "none"))]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn three_way_compare<T: Copy>(_lhs: T, _rhss: T) -> crate::cmp::Ordering {
+    unimplemented!()
+}
 
-    /// Performs checked integer addition.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `overflowing_add` method. For example,
-    /// [`u32::overflowing_add`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
+/// Performs checked integer addition.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `overflowing_add` method. For example,
+/// [`u32::overflowing_add`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn add_with_overflow<T: Copy>(_x: T, _y: T) -> (T, bool) {
+    unimplemented!()
+}
 
-    /// Performs checked integer subtraction
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `overflowing_sub` method. For example,
-    /// [`u32::overflowing_sub`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
+/// Performs checked integer subtraction
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `overflowing_sub` method. For example,
+/// [`u32::overflowing_sub`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn sub_with_overflow<T: Copy>(_x: T, _y: T) -> (T, bool) {
+    unimplemented!()
+}
 
-    /// Performs checked integer multiplication
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `overflowing_mul` method. For example,
-    /// [`u32::overflowing_mul`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
+/// Performs checked integer multiplication
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `overflowing_mul` method. For example,
+/// [`u32::overflowing_mul`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn mul_with_overflow<T: Copy>(_x: T, _y: T) -> (T, bool) {
+    unimplemented!()
+}
 
-    /// Performs an exact division, resulting in undefined behavior where
-    /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_const_unstable(feature = "const_exact_div", issue = "none")]
-    #[rustc_nounwind]
-    pub fn exact_div<T: Copy>(x: T, y: T) -> T;
+/// Performs an exact division, resulting in undefined behavior where
+/// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
+///
+/// This intrinsic does not have a stable counterpart.
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_exact_div", issue = "none"))]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn exact_div<T: Copy>(_x: T, _y: T) -> T {
+    unimplemented!()
+}
 
-    /// Performs an unchecked division, resulting in undefined behavior
-    /// where `y == 0` or `x == T::MIN && y == -1`
-    ///
-    /// Safe wrappers for this intrinsic are available on the integer
-    /// primitives via the `checked_div` method. For example,
-    /// [`u32::checked_div`]
-    #[cfg_attr(
-        bootstrap,
-        rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0")
-    )]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
-    /// Returns the remainder of an unchecked division, resulting in
-    /// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
-    ///
-    /// Safe wrappers for this intrinsic are available on the integer
-    /// primitives via the `checked_rem` method. For example,
-    /// [`u32::checked_rem`]
-    #[cfg_attr(
-        bootstrap,
-        rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0")
-    )]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
+/// Performs an unchecked division, resulting in undefined behavior
+/// where `y == 0` or `x == T::MIN && y == -1`
+///
+/// Safe wrappers for this intrinsic are available on the integer
+/// primitives via the `checked_div` method. For example,
+/// [`u32::checked_div`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_div<T: Copy>(_x: T, _y: T) -> T {
+    unimplemented!()
+}
+/// Returns the remainder of an unchecked division, resulting in
+/// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
+///
+/// Safe wrappers for this intrinsic are available on the integer
+/// primitives via the `checked_rem` method. For example,
+/// [`u32::checked_rem`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_rem<T: Copy>(_x: T, _y: T) -> T {
+    unimplemented!()
+}
 
-    /// Performs an unchecked left shift, resulting in undefined behavior when
-    /// `y < 0` or `y >= N`, where N is the width of T in bits.
-    ///
-    /// Safe wrappers for this intrinsic are available on the integer
-    /// primitives via the `checked_shl` method. For example,
-    /// [`u32::checked_shl`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_shl<T: Copy, U: Copy>(x: T, y: U) -> T;
-    /// Performs an unchecked right shift, resulting in undefined behavior when
-    /// `y < 0` or `y >= N`, where N is the width of T in bits.
-    ///
-    /// Safe wrappers for this intrinsic are available on the integer
-    /// primitives via the `checked_shr` method. For example,
-    /// [`u32::checked_shr`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_shr<T: Copy, U: Copy>(x: T, y: U) -> T;
+/// Performs an unchecked left shift, resulting in undefined behavior when
+/// `y < 0` or `y >= N`, where N is the width of T in bits.
+///
+/// Safe wrappers for this intrinsic are available on the integer
+/// primitives via the `checked_shl` method. For example,
+/// [`u32::checked_shl`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_shl<T: Copy, U: Copy>(_x: T, _y: U) -> T {
+    unimplemented!()
+}
+/// Performs an unchecked right shift, resulting in undefined behavior when
+/// `y < 0` or `y >= N`, where N is the width of T in bits.
+///
+/// Safe wrappers for this intrinsic are available on the integer
+/// primitives via the `checked_shr` method. For example,
+/// [`u32::checked_shr`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_shr<T: Copy, U: Copy>(_x: T, _y: U) -> T {
+    unimplemented!()
+}
 
-    /// Returns the result of an unchecked addition, resulting in
-    /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
-    ///
-    /// The stable counterpart of this intrinsic is `unchecked_add` on the various
-    /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`].
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
+/// Returns the result of an unchecked addition, resulting in
+/// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
+///
+/// The stable counterpart of this intrinsic is `unchecked_add` on the various
+/// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`].
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_add<T: Copy>(_x: T, _y: T) -> T {
+    unimplemented!()
+}
 
-    /// Returns the result of an unchecked subtraction, resulting in
-    /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
-    ///
-    /// The stable counterpart of this intrinsic is `unchecked_sub` on the various
-    /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`].
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
+/// Returns the result of an unchecked subtraction, resulting in
+/// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
+///
+/// The stable counterpart of this intrinsic is `unchecked_sub` on the various
+/// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`].
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_sub<T: Copy>(_x: T, _y: T) -> T {
+    unimplemented!()
+}
 
-    /// Returns the result of an unchecked multiplication, resulting in
-    /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
-    ///
-    /// The stable counterpart of this intrinsic is `unchecked_mul` on the various
-    /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`].
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
+/// Returns the result of an unchecked multiplication, resulting in
+/// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
+///
+/// The stable counterpart of this intrinsic is `unchecked_mul` on the various
+/// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`].
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn unchecked_mul<T: Copy>(_x: T, _y: T) -> T {
+    unimplemented!()
+}
 
-    /// Performs rotate left.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `rotate_left` method. For example,
-    /// [`u32::rotate_left`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn rotate_left<T: Copy>(x: T, shift: u32) -> T;
+/// Performs rotate left.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `rotate_left` method. For example,
+/// [`u32::rotate_left`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn rotate_left<T: Copy>(_x: T, _shift: u32) -> T {
+    unimplemented!()
+}
 
-    /// Performs rotate right.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `rotate_right` method. For example,
-    /// [`u32::rotate_right`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn rotate_right<T: Copy>(x: T, shift: u32) -> T;
+/// Performs rotate right.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `rotate_right` method. For example,
+/// [`u32::rotate_right`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn rotate_right<T: Copy>(_x: T, _shift: u32) -> T {
+    unimplemented!()
+}
 
-    /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `wrapping_add` method. For example,
-    /// [`u32::wrapping_add`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
-    /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `wrapping_sub` method. For example,
-    /// [`u32::wrapping_sub`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
-    /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `wrapping_mul` method. For example,
-    /// [`u32::wrapping_mul`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T;
+/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `wrapping_add` method. For example,
+/// [`u32::wrapping_add`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn wrapping_add<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
+/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `wrapping_sub` method. For example,
+/// [`u32::wrapping_sub`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn wrapping_sub<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
+/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `wrapping_mul` method. For example,
+/// [`u32::wrapping_mul`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn wrapping_mul<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
 
-    /// Computes `a + b`, saturating at numeric bounds.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `saturating_add` method. For example,
-    /// [`u32::saturating_add`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
-    /// Computes `a - b`, saturating at numeric bounds.
-    ///
-    /// 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.
-    ///
-    /// The stabilized versions of this intrinsic are available on the integer
-    /// primitives via the `saturating_sub` method. For example,
-    /// [`u32::saturating_sub`]
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn saturating_sub<T: Copy>(a: T, b: T) -> T;
+/// Computes `a + b`, saturating at numeric bounds.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `saturating_add` method. For example,
+/// [`u32::saturating_add`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn saturating_add<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
+/// Computes `a - b`, saturating at numeric bounds.
+///
+/// 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.
+///
+/// The stabilized versions of this intrinsic are available on the integer
+/// primitives via the `saturating_sub` method. For example,
+/// [`u32::saturating_sub`]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn saturating_sub<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
 
-    /// This is an implementation detail of [`crate::ptr::read`] and should
-    /// not be used anywhere else.  See its comments for why this exists.
-    ///
-    /// This intrinsic can *only* be called where the pointer is a local without
-    /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
-    /// trivially obeys runtime-MIR rules about derefs in operands.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_read", since = "1.71.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn read_via_copy<T>(ptr: *const T) -> T;
+/// This is an implementation detail of [`crate::ptr::read`] and should
+/// not be used anywhere else.  See its comments for why this exists.
+///
+/// This intrinsic can *only* be called where the pointer is a local without
+/// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
+/// trivially obeys runtime-MIR rules about derefs in operands.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_read", since = "1.71.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn read_via_copy<T>(_ptr: *const T) -> T {
+    unimplemented!()
+}
 
-    /// This is an implementation detail of [`crate::ptr::write`] and should
-    /// not be used anywhere else.  See its comments for why this exists.
-    ///
-    /// This intrinsic can *only* be called where the pointer is a local without
-    /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
-    /// that it trivially obeys runtime-MIR rules about derefs in operands.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn write_via_move<T>(ptr: *mut T, value: T);
+/// This is an implementation detail of [`crate::ptr::write`] and should
+/// not be used anywhere else.  See its comments for why this exists.
+///
+/// This intrinsic can *only* be called where the pointer is a local without
+/// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
+/// that it trivially obeys runtime-MIR rules about derefs in operands.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn write_via_move<T>(_ptr: *mut T, _value: T) {
+    unimplemented!()
+}
 
-    /// Returns the value of the discriminant for the variant in 'v';
-    /// if `T` has no discriminant, returns `0`.
-    ///
-    /// 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.
-    ///
-    /// The stabilized version of this intrinsic is [`core::mem::discriminant`].
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_discriminant", since = "1.75.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+/// Returns the value of the discriminant for the variant in 'v';
+/// if `T` has no discriminant, returns `0`.
+///
+/// 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.
+///
+/// The stabilized version of this intrinsic is [`core::mem::discriminant`].
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_discriminant", since = "1.75.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn discriminant_value<T>(_v: &T) -> <T as DiscriminantKind>::Discriminant {
+    unimplemented!()
+}
 
+extern "rust-intrinsic" {
     /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
     /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
     ///
@@ -2638,25 +2771,32 @@ extern "rust-intrinsic" {
     /// in ways that are not allowed for regular writes).
     #[rustc_nounwind]
     pub fn nontemporal_store<T>(ptr: *mut T, val: T);
+}
 
-    /// See documentation of `<*const T>::offset_from` for details.
-    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0"))]
-    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-    #[rustc_nounwind]
-    pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
+/// See documentation of `<*const T>::offset_from` for details.
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0"))]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn ptr_offset_from<T>(_ptr: *const T, _base: *const T) -> isize {
+    unimplemented!()
+}
 
-    /// See documentation of `<*const T>::sub_ptr` for details.
-    #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
-    #[rustc_nounwind]
-    pub fn ptr_offset_from_unsigned<T>(ptr: *const T, base: *const T) -> usize;
+/// See documentation of `<*const T>::sub_ptr` for details.
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892"))]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn ptr_offset_from_unsigned<T>(_ptr: *const T, _base: *const T) -> usize {
+    unimplemented!()
 }
 
 /// 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")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020"))]
 #[rustc_intrinsic]
 #[rustc_nounwind]
 #[rustc_do_not_const_check]
@@ -2666,59 +2806,71 @@ pub const fn ptr_guaranteed_cmp<T>(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
-    /// comparing `i96`s instead of forcing `alloca`s for `[6 x i16]`.
-    ///
-    /// Above some backend-decided threshold this will emit calls to `memcmp`,
-    /// like slice equality does, instead of causing massive code size.
-    ///
-    /// Since this works by comparing the underlying bytes, the actual `T` is
-    /// not particularly important.  It will be used for its size and alignment,
-    /// but any validity restrictions will be ignored, not enforced.
-    ///
-    /// # Safety
-    ///
-    /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
-    /// Note that this is a stricter criterion than just the *values* being
-    /// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
-    ///
-    /// At compile-time, it is furthermore UB to call this if any of the bytes
-    /// in `*a` or `*b` have provenance.
-    ///
-    /// (The implementation is allowed to branch on the results of comparisons,
-    /// which is UB if any of their inputs are `undef`.)
-    #[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")]
-    #[rustc_nounwind]
-    pub fn raw_eq<T>(a: &T, b: &T) -> bool;
+/// Determines whether the raw bytes of the two values are equal.
+///
+/// This is particularly handy for arrays, since it allows things like just
+/// comparing `i96`s instead of forcing `alloca`s for `[6 x i16]`.
+///
+/// Above some backend-decided threshold this will emit calls to `memcmp`,
+/// like slice equality does, instead of causing massive code size.
+///
+/// Since this works by comparing the underlying bytes, the actual `T` is
+/// not particularly important.  It will be used for its size and alignment,
+/// but any validity restrictions will be ignored, not enforced.
+///
+/// # Safety
+///
+/// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
+/// Note that this is a stricter criterion than just the *values* being
+/// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
+///
+/// At compile-time, it is furthermore UB to call this if any of the bytes
+/// in `*a` or `*b` have provenance.
+///
+/// (The implementation is allowed to branch on the results of comparisons,
+/// which is UB if any of their inputs are `undef`.)
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none"))]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn raw_eq<T>(_a: &T, _b: &T) -> bool {
+    unimplemented!()
+}
 
-    /// Lexicographically compare `[left, left + bytes)` and `[right, right + bytes)`
-    /// as unsigned bytes, returning negative if `left` is less, zero if all the
-    /// bytes match, or positive if `left` is greater.
-    ///
-    /// This underlies things like `<[u8]>::cmp`, and will usually lower to `memcmp`.
-    ///
-    /// # Safety
-    ///
-    /// `left` and `right` must each be [valid] for reads of `bytes` bytes.
-    ///
-    /// Note that this applies to the whole range, not just until the first byte
-    /// that differs.  That allows optimizations that can read in large chunks.
-    ///
-    /// [valid]: crate::ptr#safety
-    #[rustc_const_unstable(feature = "const_intrinsic_compare_bytes", issue = "none")]
-    #[rustc_nounwind]
-    pub fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32;
+/// Lexicographically compare `[left, left + bytes)` and `[right, right + bytes)`
+/// as unsigned bytes, returning negative if `left` is less, zero if all the
+/// bytes match, or positive if `left` is greater.
+///
+/// This underlies things like `<[u8]>::cmp`, and will usually lower to `memcmp`.
+///
+/// # Safety
+///
+/// `left` and `right` must each be [valid] for reads of `bytes` bytes.
+///
+/// Note that this applies to the whole range, not just until the first byte
+/// that differs.  That allows optimizations that can read in large chunks.
+///
+/// [valid]: crate::ptr#safety
+#[cfg_attr(
+    bootstrap,
+    rustc_const_unstable(feature = "const_intrinsic_compare_bytes", issue = "none")
+)]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: usize) -> i32 {
+    unimplemented!()
+}
 
-    /// See documentation of [`std::hint::black_box`] for details.
-    ///
-    /// [`std::hint::black_box`]: crate::hint::black_box
-    #[rustc_const_unstable(feature = "const_black_box", issue = "none")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn black_box<T>(dummy: T) -> T;
+/// See documentation of [`std::hint::black_box`] for details.
+///
+/// [`std::hint::black_box`]: crate::hint::black_box
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_black_box", issue = "none"))]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const fn black_box<T>(_dummy: T) -> T {
+    unimplemented!()
 }
 
 /// Selects which function to call depending on the context.
@@ -2886,7 +3038,7 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
 #[rustc_nounwind]
 #[inline]
 #[rustc_intrinsic]
-// This has fallback `const fn` MIR, so shouldn't need stability, see #122652
+// Const-unstable because `swap_nonoverlapping` is const-unstable.
 #[rustc_const_unstable(feature = "const_typed_swap", issue = "none")]
 pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
     // SAFETY: The caller provided single non-overlapping items behind
@@ -2908,8 +3060,7 @@ pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
 /// user has UB checks disabled, the checks will still get optimized out. This intrinsic is
 /// primarily used by [`ub_checks::assert_unsafe_precondition`].
 #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // just for UB checks
-#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)] // just for UB checks
 #[inline(always)]
 #[rustc_intrinsic]
 pub const fn ub_checks() -> bool {
@@ -2925,7 +3076,6 @@ pub const fn ub_checks() -> bool {
 ///    - At compile time, a compile error occurs if this constraint is violated.
 ///    - At runtime, it is not checked.
 #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
-#[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_nounwind]
 #[rustc_intrinsic]
 #[miri::intrinsic_fallback_is_spec]
@@ -2994,7 +3144,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_size_of", since = "1.40.0"))]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn size_of<T>() -> usize {
@@ -3012,7 +3162,7 @@ pub const fn size_of<T>() -> usize {
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_min_align_of", since = "1.40.0"))]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn min_align_of<T>() -> usize {
@@ -3025,7 +3175,7 @@ pub const fn min_align_of<T>() -> usize {
 /// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971).
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_const_unstable(feature = "const_pref_align_of", issue = "91971")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_pref_align_of", issue = "91971"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn pref_align_of<T>() -> usize {
@@ -3043,7 +3193,7 @@ pub const unsafe fn pref_align_of<T>() -> usize {
 /// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`].
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "variant_count", issue = "73662"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn variant_count<T>() -> usize {
@@ -3059,7 +3209,7 @@ pub const fn variant_count<T>() -> usize {
 /// See [`crate::mem::size_of_val_raw`] for safety conditions.
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_size_of_val", issue = "46571"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize {
@@ -3075,7 +3225,7 @@ pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize {
 /// See [`crate::mem::align_of_val_raw`] for safety conditions.
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_align_of_val", issue = "46571"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn min_align_of_val<T: ?Sized>(_ptr: *const T) -> usize {
@@ -3092,7 +3242,7 @@ pub const unsafe fn min_align_of_val<T: ?Sized>(_ptr: *const T) -> usize {
 /// The stabilized version of this intrinsic is [`core::any::type_name`].
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_name", issue = "63084"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn type_name<T: ?Sized>() -> &'static str {
@@ -3111,7 +3261,7 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
 /// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_id", issue = "77125"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn type_id<T: ?Sized + 'static>() -> u128 {
@@ -3126,7 +3276,7 @@ pub const fn type_id<T: ?Sized + 'static>() -> u128 {
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P {
@@ -3155,7 +3305,7 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
     bootstrap,
     cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
+#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *const P) -> M {
@@ -3261,18 +3411,13 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *cons
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_copy_nonoverlapping"]
 pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
-    extern "rust-intrinsic" {
-        #[cfg_attr(
-            bootstrap,
-            rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")
-        )]
-        #[cfg_attr(
-            not(bootstrap),
-            rustc_const_unstable(feature = "core_intrinsics", issue = "none")
-        )]
-        #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-        #[rustc_nounwind]
-        pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    const unsafe fn copy_nonoverlapping<T>(_src: *const T, _dst: *mut T, _count: usize) {
+        unreachable!()
     }
 
     ub_checks::assert_unsafe_precondition!(
@@ -3373,18 +3518,13 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_copy"]
 pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
-    extern "rust-intrinsic" {
-        #[cfg_attr(
-            bootstrap,
-            rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")
-        )]
-        #[cfg_attr(
-            not(bootstrap),
-            rustc_const_unstable(feature = "core_intrinsics", issue = "none")
-        )]
-        #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-        #[rustc_nounwind]
-        fn copy<T>(src: *const T, dst: *mut T, count: usize);
+    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    const unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
+        unreachable!()
     }
 
     // SAFETY: the safety contract for `copy` must be upheld by the caller.
@@ -3462,11 +3602,13 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_write_bytes"]
 pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
-    extern "rust-intrinsic" {
-        #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))]
-        #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
-        #[rustc_nounwind]
-        fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
+    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    const unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
+        unreachable!()
     }
 
     // SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
@@ -3494,8 +3636,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
 /// The stabilized version of this intrinsic is
 /// [`f16::min`]
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f16", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn minnumf16(_x: f16, _y: f16) -> f16 {
@@ -3512,7 +3653,7 @@ pub const fn minnumf16(_x: f16, _y: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::min`]
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn minnumf32(_x: f32, _y: f32) -> f32 {
@@ -3529,7 +3670,7 @@ pub const fn minnumf32(_x: f32, _y: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::min`]
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn minnumf64(_x: f64, _y: f64) -> f64 {
@@ -3546,8 +3687,7 @@ pub const fn minnumf64(_x: f64, _y: f64) -> f64 {
 /// The stabilized version of this intrinsic is
 /// [`f128::min`]
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f128", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn minnumf128(_x: f128, _y: f128) -> f128 {
@@ -3564,8 +3704,7 @@ pub const fn minnumf128(_x: f128, _y: f128) -> f128 {
 /// The stabilized version of this intrinsic is
 /// [`f16::max`]
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f16", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn maxnumf16(_x: f16, _y: f16) -> f16 {
@@ -3582,7 +3721,7 @@ pub const fn maxnumf16(_x: f16, _y: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::max`]
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn maxnumf32(_x: f32, _y: f32) -> f32 {
@@ -3599,7 +3738,7 @@ pub const fn maxnumf32(_x: f32, _y: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::max`]
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn maxnumf64(_x: f64, _y: f64) -> f64 {
@@ -3616,8 +3755,7 @@ pub const fn maxnumf64(_x: f64, _y: f64) -> f64 {
 /// The stabilized version of this intrinsic is
 /// [`f128::max`]
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f128", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn maxnumf128(_x: f128, _y: f128) -> f128 {
@@ -3629,8 +3767,7 @@ pub const fn maxnumf128(_x: f128, _y: f128) -> f128 {
 /// The stabilized version of this intrinsic is
 /// [`f16::abs`](../../std/primitive.f16.html#method.abs)
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f16", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn fabsf16(_x: f16) -> f16 {
@@ -3642,7 +3779,7 @@ pub const unsafe fn fabsf16(_x: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::abs`](../../std/primitive.f32.html#method.abs)
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn fabsf32(_x: f32) -> f32 {
@@ -3654,7 +3791,7 @@ pub const unsafe fn fabsf32(_x: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::abs`](../../std/primitive.f64.html#method.abs)
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn fabsf64(_x: f64) -> f64 {
@@ -3666,8 +3803,7 @@ pub const unsafe fn fabsf64(_x: f64) -> f64 {
 /// The stabilized version of this intrinsic is
 /// [`f128::abs`](../../std/primitive.f128.html#method.abs)
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f128", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn fabsf128(_x: f128) -> f128 {
@@ -3679,8 +3815,7 @@ pub const unsafe fn fabsf128(_x: f128) -> f128 {
 /// The stabilized version of this intrinsic is
 /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign)
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f16", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 {
@@ -3692,7 +3827,7 @@ pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign)
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 {
@@ -3703,7 +3838,7 @@ pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign)
 #[rustc_nounwind]
-#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 {
@@ -3715,8 +3850,7 @@ pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 {
 /// The stabilized version of this intrinsic is
 /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign)
 #[rustc_nounwind]
-// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-#[rustc_const_unstable(feature = "f128", issue = "116909")]
+#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 {
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 12f6997dbeae7..444f733adff00 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -107,6 +107,7 @@
 //
 // Library features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(const_exact_div))]
 #![cfg_attr(bootstrap, feature(const_fmt_arguments_new))]
 #![feature(array_ptr_get)]
 #![feature(asm_experimental_arch)]
@@ -116,7 +117,6 @@
 #![feature(const_black_box)]
 #![feature(const_char_encode_utf16)]
 #![feature(const_eval_select)]
-#![feature(const_exact_div)]
 #![feature(const_float_methods)]
 #![feature(const_heap)]
 #![feature(const_nonnull_new)]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 0c5bf58564781..b9706ea2a9e35 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -1,4 +1,5 @@
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(const_three_way_compare))]
 #![cfg_attr(bootstrap, feature(strict_provenance))]
 #![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
 #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
@@ -22,7 +23,6 @@
 #![feature(const_nonnull_new)]
 #![feature(const_option_ext)]
 #![feature(const_pin_2)]
-#![feature(const_three_way_compare)]
 #![feature(const_trait_impl)]
 #![feature(core_intrinsics)]
 #![feature(core_io_borrowed_buf)]
diff --git a/tests/rustdoc/const-intrinsic.rs b/tests/rustdoc/const-intrinsic.rs
index 520e253469c63..8444d4a3aa768 100644
--- a/tests/rustdoc/const-intrinsic.rs
+++ b/tests/rustdoc/const-intrinsic.rs
@@ -1,20 +1,26 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![feature(staged_api)]
 
 #![crate_name = "foo"]
 #![stable(since="1.0.0", feature="rust1")]
 
-extern "rust-intrinsic" {
-    //@ has 'foo/fn.transmute.html'
-    //@ has - '//pre[@class="rust item-decl"]' 'pub const unsafe extern "rust-intrinsic" fn transmute<T, U>(_: T) -> U'
-    #[stable(since="1.0.0", feature="rust1")]
-    #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
-    pub fn transmute<T, U>(_: T) -> U;
+//@ has 'foo/fn.transmute.html'
+//@ has - '//pre[@class="rust item-decl"]' 'pub const unsafe fn transmute<T, U>(_: T) -> U'
+#[stable(since="1.0.0", feature="rust1")]
+#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn transmute<T, U>(_: T) -> U {
+    loop {}
+}
 
-    //@ has 'foo/fn.unreachable.html'
-    //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
-    #[stable(since="1.0.0", feature="rust1")]
-    pub fn unreachable() -> !;
+//@ has 'foo/fn.unreachable.html'
+//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
+#[stable(since="1.0.0", feature="rust1")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub unsafe fn unreachable() -> ! {
+    loop {}
 }
 
 extern "C" {
diff --git a/tests/ui/closures/coerce-unsafe-to-closure.stderr b/tests/ui/closures/coerce-unsafe-to-closure.stderr
index 2538fc0361c37..013b9009da406 100644
--- a/tests/ui/closures/coerce-unsafe-to-closure.stderr
+++ b/tests/ui/closures/coerce-unsafe-to-closure.stderr
@@ -1,4 +1,4 @@
-error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
+error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
   --> $DIR/coerce-unsafe-to-closure.rs:2:44
    |
 LL |     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
@@ -6,7 +6,7 @@ LL |     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
    |                                        |
    |                                        required by a bound introduced by this call
    |
-   = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
+   = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
    = note: unsafe function cannot be called generically without an unsafe block
 note: required by a bound in `Option::<T>::map`
   --> $SRC_DIR/core/src/option.rs:LL:COL
diff --git a/tests/ui/consts/auxiliary/unstable_intrinsic.rs b/tests/ui/consts/auxiliary/unstable_intrinsic.rs
index edef499dbb182..9e53a8feb5dc5 100644
--- a/tests/ui/consts/auxiliary/unstable_intrinsic.rs
+++ b/tests/ui/consts/auxiliary/unstable_intrinsic.rs
@@ -1,26 +1,13 @@
 #![feature(staged_api, rustc_attrs, intrinsics)]
 #![stable(since="1.0.0", feature = "stable")]
 
-#[stable(since="1.0.0", feature = "stable")]
-pub mod old_way {
-    extern "rust-intrinsic" {
-        #[unstable(feature = "unstable", issue = "42")]
-        pub fn size_of_val<T>(x: *const T) -> usize;
-
-        #[unstable(feature = "unstable", issue = "42")]
-        #[rustc_const_unstable(feature = "unstable", issue = "42")]
-        pub fn min_align_of_val<T>(x: *const T) -> usize;
-    }
-}
-
-#[stable(since="1.0.0", feature = "stable")]
-pub mod new_way {
-    #[unstable(feature = "unstable", issue = "42")]
-    #[rustc_intrinsic]
-    pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
-
-    #[unstable(feature = "unstable", issue = "42")]
-    #[rustc_const_unstable(feature = "unstable", issue = "42")]
-    #[rustc_intrinsic]
-    pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
-}
+#[unstable(feature = "unstable", issue = "42")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
+
+#[unstable(feature = "unstable", issue = "42")]
+#[rustc_const_unstable(feature = "unstable", issue = "42")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
diff --git a/tests/ui/consts/const-compare-bytes-ub.rs b/tests/ui/consts/const-compare-bytes-ub.rs
index 903ba15e62291..9dafae1efd1a6 100644
--- a/tests/ui/consts/const-compare-bytes-ub.rs
+++ b/tests/ui/consts/const-compare-bytes-ub.rs
@@ -1,7 +1,6 @@
 //@ check-fail
 
 #![feature(core_intrinsics)]
-#![feature(const_intrinsic_compare_bytes)]
 use std::intrinsics::compare_bytes;
 use std::mem::MaybeUninit;
 
diff --git a/tests/ui/consts/const-compare-bytes-ub.stderr b/tests/ui/consts/const-compare-bytes-ub.stderr
index 7f83dee640969..9ef5c8ad43a1c 100644
--- a/tests/ui/consts/const-compare-bytes-ub.stderr
+++ b/tests/ui/consts/const-compare-bytes-ub.stderr
@@ -1,47 +1,47 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:10:9
+  --> $DIR/const-compare-bytes-ub.rs:9:9
    |
 LL |         compare_bytes(0 as *const u8, 2 as *const u8, 1)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 1 byte of memory, but got a null pointer
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:14:9
+  --> $DIR/const-compare-bytes-ub.rs:13:9
    |
 LL |         compare_bytes(1 as *const u8, 0 as *const u8, 1)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 1 byte of memory, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:18:9
+  --> $DIR/const-compare-bytes-ub.rs:17:9
    |
 LL |         compare_bytes(1 as *const u8, 2 as *const u8, 1)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 1 byte of memory, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:22:9
+  --> $DIR/const-compare-bytes-ub.rs:21:9
    |
 LL |         compare_bytes([1, 2, 3].as_ptr(), [1, 2, 3, 4].as_ptr(), 4)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0 which is only 3 bytes from the end of the allocation
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:26:9
+  --> $DIR/const-compare-bytes-ub.rs:25:9
    |
 LL |         compare_bytes([1, 2, 3, 4].as_ptr(), [1, 2, 3].as_ptr(), 4)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC1 which is only 3 bytes from the end of the allocation
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:30:9
+  --> $DIR/const-compare-bytes-ub.rs:29:9
    |
 LL |         compare_bytes(MaybeUninit::uninit().as_ptr(), [1].as_ptr(), 1)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:34:9
+  --> $DIR/const-compare-bytes-ub.rs:33:9
    |
 LL |         compare_bytes([1].as_ptr(), MaybeUninit::uninit().as_ptr(), 1)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC3[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-compare-bytes-ub.rs:38:9
+  --> $DIR/const-compare-bytes-ub.rs:37:9
    |
 LL |         compare_bytes([&1].as_ptr().cast(), [&2].as_ptr().cast(), std::mem::size_of::<usize>())
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer
diff --git a/tests/ui/consts/const-compare-bytes.rs b/tests/ui/consts/const-compare-bytes.rs
index 8596a2d9df910..cd5cdfd0400ec 100644
--- a/tests/ui/consts/const-compare-bytes.rs
+++ b/tests/ui/consts/const-compare-bytes.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![feature(core_intrinsics)]
-#![feature(const_intrinsic_compare_bytes)]
 use std::intrinsics::compare_bytes;
 
 fn main() {
diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs
index 57d4b4888caa9..e5873ea26e8d8 100644
--- a/tests/ui/consts/const-eval/simd/insert_extract.rs
+++ b/tests/ui/consts/const-eval/simd/insert_extract.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![feature(repr_simd)]
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![feature(staged_api)]
 #![stable(feature = "foo", since = "1.3.37")]
 #![allow(non_camel_case_types)]
@@ -10,14 +10,18 @@
 #[repr(simd)] struct u16x2([u16; 2]);
 #[repr(simd)] struct f32x4([f32; 4]);
 
-extern "rust-intrinsic" {
-    #[stable(feature = "foo", since = "1.3.37")]
-    #[rustc_const_stable(feature = "foo", since = "1.3.37")]
-    fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
+#[stable(feature = "foo", since = "1.3.37")]
+#[rustc_const_stable(feature = "foo", since = "1.3.37")]
+#[rustc_intrinsic]
+const unsafe fn simd_insert<T, U>(_x: T, _idx: u32, _val: U) -> T {
+    unimplemented!()
+}
 
-    #[stable(feature = "foo", since = "1.3.37")]
-    #[rustc_const_stable(feature = "foo", since = "1.3.37")]
-    fn simd_extract<T, U>(x: T, idx: u32) -> U;
+#[stable(feature = "foo", since = "1.3.37")]
+#[rustc_const_stable(feature = "foo", since = "1.3.37")]
+#[rustc_intrinsic]
+const unsafe fn simd_extract<T, U>(_x: T, _idx: u32) -> U {
+    unimplemented!()
 }
 
 fn main() {
diff --git a/tests/ui/consts/const-unstable-intrinsic.rs b/tests/ui/consts/const-unstable-intrinsic.rs
index 5d43cdf5da6df..56b552b6a3f35 100644
--- a/tests/ui/consts/const-unstable-intrinsic.rs
+++ b/tests/ui/consts/const-unstable-intrinsic.rs
@@ -14,63 +14,51 @@ fn main() {
 const fn const_main() {
     let x = 42;
     unsafe {
-        unstable_intrinsic::old_way::size_of_val(&x);
-        //~^ERROR: unstable library feature `unstable`
-        //~|ERROR: cannot call non-const intrinsic
-        unstable_intrinsic::old_way::min_align_of_val(&x);
-        //~^ERROR: unstable library feature `unstable`
-        //~|ERROR: not yet stable as a const intrinsic
-        unstable_intrinsic::new_way::size_of_val(&x);
+        unstable_intrinsic::size_of_val(&x);
         //~^ERROR: unstable library feature `unstable`
         //~|ERROR: cannot be (indirectly) exposed to stable
-        unstable_intrinsic::new_way::min_align_of_val(&x);
+        unstable_intrinsic::min_align_of_val(&x);
         //~^ERROR: unstable library feature `unstable`
         //~|ERROR: not yet stable as a const intrinsic
 
-        old_way::size_of_val(&x);
-        //~^ERROR: cannot call non-const intrinsic
-        old_way::min_align_of_val(&x);
-        //~^ERROR: cannot use `#[feature(local)]`
-        new_way::size_of_val(&x);
+        size_of_val(&x);
         //~^ERROR: cannot be (indirectly) exposed to stable
-        new_way::min_align_of_val(&x);
+        min_align_of_val(&x);
         //~^ERROR: cannot use `#[feature(local)]`
     }
 }
 
-#[stable(since="1.0.0", feature = "stable")]
-pub mod old_way {
-    extern "rust-intrinsic" {
-        #[unstable(feature = "local", issue = "42")]
-        pub fn size_of_val<T>(x: *const T) -> usize;
-
-        #[unstable(feature = "local", issue = "42")]
-        #[rustc_const_unstable(feature = "local", issue = "42")]
-        pub fn min_align_of_val<T>(x: *const T) -> usize;
-    }
-}
-
-#[stable(since="1.0.0", feature = "stable")]
-pub mod new_way {
-    #[unstable(feature = "local", issue = "42")]
-    #[rustc_intrinsic]
-    pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
+#[unstable(feature = "local", issue = "42")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
 
-    #[unstable(feature = "local", issue = "42")]
-    #[rustc_const_unstable(feature = "local", issue = "42")]
-    #[rustc_intrinsic]
-    pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
-}
+#[unstable(feature = "local", issue = "42")]
+#[rustc_const_unstable(feature = "local", issue = "42")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub const unsafe fn min_align_of_val<T>(x: *const T) -> usize { 42 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
 #[inline]
 pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
     // Const stability attributes are not inherited from parent items.
-    extern "rust-intrinsic" {
-        fn copy<T>(src: *const T, dst: *mut T, count: usize);
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+        unimplemented!()
     }
 
     unsafe { copy(src, dst, count) }
-    //~^ ERROR cannot call non-const intrinsic
+    //~^ ERROR cannot be (indirectly) exposed to stable
+}
+
+// Ensure that a fallback body is recursively-const-checked.
+mod fallback {
+    #[rustc_intrinsic]
+    const unsafe fn copy<T>(src: *const T, _dst: *mut T, _count: usize) {
+        super::size_of_val(src);
+        //~^ ERROR cannot be (indirectly) exposed to stable
+    }
 }
diff --git a/tests/ui/consts/const-unstable-intrinsic.stderr b/tests/ui/consts/const-unstable-intrinsic.stderr
index c2e38f54dc637..3e605f3d0037e 100644
--- a/tests/ui/consts/const-unstable-intrinsic.stderr
+++ b/tests/ui/consts/const-unstable-intrinsic.stderr
@@ -1,8 +1,8 @@
 error[E0658]: use of unstable library feature `unstable`
   --> $DIR/const-unstable-intrinsic.rs:17:9
    |
-LL |         unstable_intrinsic::old_way::size_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         unstable_intrinsic::size_of_val(&x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #42 <https://github.com/rust-lang/rust/issues/42> for more information
    = help: add `#![feature(unstable)]` to the crate attributes to enable
@@ -11,74 +11,42 @@ LL |         unstable_intrinsic::old_way::size_of_val(&x);
 error[E0658]: use of unstable library feature `unstable`
   --> $DIR/const-unstable-intrinsic.rs:20:9
    |
-LL |         unstable_intrinsic::old_way::min_align_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #42 <https://github.com/rust-lang/rust/issues/42> for more information
-   = help: add `#![feature(unstable)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: use of unstable library feature `unstable`
-  --> $DIR/const-unstable-intrinsic.rs:23:9
-   |
-LL |         unstable_intrinsic::new_way::size_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         unstable_intrinsic::min_align_of_val(&x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #42 <https://github.com/rust-lang/rust/issues/42> for more information
    = help: add `#![feature(unstable)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: use of unstable library feature `unstable`
-  --> $DIR/const-unstable-intrinsic.rs:26:9
-   |
-LL |         unstable_intrinsic::new_way::min_align_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #42 <https://github.com/rust-lang/rust/issues/42> for more information
-   = help: add `#![feature(unstable)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: cannot call non-const intrinsic `size_of_val` in constant functions
+error: intrinsic `unstable_intrinsic::size_of_val` cannot be (indirectly) exposed to stable
   --> $DIR/const-unstable-intrinsic.rs:17:9
    |
-LL |         unstable_intrinsic::old_way::size_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         unstable_intrinsic::size_of_val(&x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
 
 error: `min_align_of_val` is not yet stable as a const intrinsic
   --> $DIR/const-unstable-intrinsic.rs:20:9
    |
-LL |         unstable_intrinsic::old_way::min_align_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         unstable_intrinsic::min_align_of_val(&x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(unstable)]` to the crate attributes to enable
 
-error: intrinsic `unstable_intrinsic::new_way::size_of_val` cannot be (indirectly) exposed to stable
-  --> $DIR/const-unstable-intrinsic.rs:23:9
+error: intrinsic `size_of_val` cannot be (indirectly) exposed to stable
+  --> $DIR/const-unstable-intrinsic.rs:24:9
    |
-LL |         unstable_intrinsic::new_way::size_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         size_of_val(&x);
+   |         ^^^^^^^^^^^^^^^
    |
-   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_indirect]` (but this requires team approval)
-
-error: `min_align_of_val` is not yet stable as a const intrinsic
-  --> $DIR/const-unstable-intrinsic.rs:26:9
-   |
-LL |         unstable_intrinsic::new_way::min_align_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(unstable)]` to the crate attributes to enable
-
-error: cannot call non-const intrinsic `size_of_val` in constant functions
-  --> $DIR/const-unstable-intrinsic.rs:30:9
-   |
-LL |         old_way::size_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
 
 error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
-  --> $DIR/const-unstable-intrinsic.rs:32:9
+  --> $DIR/const-unstable-intrinsic.rs:26:9
    |
-LL |         old_way::min_align_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         min_align_of_val(&x);
+   |         ^^^^^^^^^^^^^^^^^^^^
    |
 help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
    |
@@ -91,37 +59,22 @@ LL + #[rustc_allow_const_fn_unstable(local)]
 LL | const fn const_main() {
    |
 
-error: intrinsic `new_way::size_of_val` cannot be (indirectly) exposed to stable
-  --> $DIR/const-unstable-intrinsic.rs:34:9
+error: intrinsic `copy::copy` cannot be (indirectly) exposed to stable
+  --> $DIR/const-unstable-intrinsic.rs:53:14
    |
-LL |         new_way::size_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { copy(src, dst, count) }
+   |              ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_indirect]` (but this requires team approval)
+   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
 
-error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
-  --> $DIR/const-unstable-intrinsic.rs:36:9
-   |
-LL |         new_way::min_align_of_val(&x);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+error: intrinsic `size_of_val` cannot be (indirectly) exposed to stable
+  --> $DIR/const-unstable-intrinsic.rs:61:9
    |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn const_main() {
-   |
-help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+LL |         super::size_of_val(src);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
-LL + #[rustc_allow_const_fn_unstable(local)]
-LL | const fn const_main() {
-   |
-
-error: cannot call non-const intrinsic `copy` in constant functions
-  --> $DIR/const-unstable-intrinsic.rs:74:14
-   |
-LL |     unsafe { copy(src, dst, count) }
-   |              ^^^^^^^^^^^^^^^^^^^^^
+   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
 
-error: aborting due to 13 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/consts/copy-intrinsic.rs b/tests/ui/consts/copy-intrinsic.rs
index 62917c0b98b2c..08fbcc107e7ec 100644
--- a/tests/ui/consts/copy-intrinsic.rs
+++ b/tests/ui/consts/copy-intrinsic.rs
@@ -1,17 +1,21 @@
 #![stable(feature = "dummy", since = "1.0.0")]
 
 // ignore-tidy-linelength
-#![feature(intrinsics, staged_api)]
+#![feature(intrinsics, staged_api, rustc_attrs)]
 use std::mem;
 
-extern "rust-intrinsic" {
-    #[stable(feature = "dummy", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
-    fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+#[stable(feature = "dummy", since = "1.0.0")]
+#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+#[rustc_intrinsic]
+const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+    unimplemented!()
+}
 
-    #[stable(feature = "dummy", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
-    fn copy<T>(src: *const T, dst: *mut T, count: usize);
+#[stable(feature = "dummy", since = "1.0.0")]
+#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+#[rustc_intrinsic]
+const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+    unimplemented!()
 }
 
 const COPY_ZERO: () = unsafe {
diff --git a/tests/ui/consts/copy-intrinsic.stderr b/tests/ui/consts/copy-intrinsic.stderr
index 29a88f6270bc6..41af3a2cd2dc2 100644
--- a/tests/ui/consts/copy-intrinsic.stderr
+++ b/tests/ui/consts/copy-intrinsic.stderr
@@ -1,23 +1,23 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/copy-intrinsic.rs:30:5
+  --> $DIR/copy-intrinsic.rs:34:5
    |
 LL |     copy_nonoverlapping(0x100 as *const i32, dangle, 1);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got 0x100[noalloc] which is a dangling pointer (it has no provenance)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/copy-intrinsic.rs:39:5
+  --> $DIR/copy-intrinsic.rs:43:5
    |
 LL |     copy_nonoverlapping(dangle, 0x100 as *mut i32, 1);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x28 which is at or beyond the end of the allocation of size 4 bytes
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/copy-intrinsic.rs:46:5
+  --> $DIR/copy-intrinsic.rs:50:5
    |
 LL |     copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/copy-intrinsic.rs:52:5
+  --> $DIR/copy-intrinsic.rs:56:5
    |
 LL |     copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
index 99f98c3f27ada..76b6a8c8395cc 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
@@ -1,5 +1,4 @@
 #![feature(core_intrinsics)]
-#![feature(const_intrinsic_raw_eq)]
 
 const RAW_EQ_PADDING: bool = unsafe {
     std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
index bedfc8283ea45..b8fdfe7bef35a 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
@@ -1,11 +1,11 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/intrinsic-raw_eq-const-bad.rs:5:5
+  --> $DIR/intrinsic-raw_eq-const-bad.rs:4:5
    |
 LL |     std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/intrinsic-raw_eq-const-bad.rs:11:5
+  --> $DIR/intrinsic-raw_eq-const-bad.rs:10:5
    |
 LL |     std::intrinsics::raw_eq(&(&0), &(&1))
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer
@@ -14,7 +14,7 @@ LL |     std::intrinsics::raw_eq(&(&0), &(&1))
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/intrinsic-raw_eq-const-bad.rs:19:5
+  --> $DIR/intrinsic-raw_eq-const-bad.rs:18:5
    |
 LL |     std::intrinsics::raw_eq(aref, aref)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const.rs
index 47b4e20dfbb7e..b37def85bb7c2 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const.rs
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![feature(core_intrinsics)]
-#![feature(const_intrinsic_raw_eq)]
 
 pub fn main() {
     use std::intrinsics::raw_eq;
diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr
index 21b7bf4e1cb83..7af17147f28f0 100644
--- a/tests/ui/intrinsics/reify-intrinsic.stderr
+++ b/tests/ui/intrinsics/reify-intrinsic.stderr
@@ -7,9 +7,9 @@ LL |     let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr
    |            expected due to this
    |
    = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize`
-                 found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
+                 found fn item `unsafe fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
 
-error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
+error[E0606]: casting `unsafe fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
   --> $DIR/reify-intrinsic.rs:11:13
    |
 LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs
index 2509416ad87d4..2b6bbf1265083 100644
--- a/tests/ui/repr/16-bit-repr-c-enum.rs
+++ b/tests/ui/repr/16-bit-repr-c-enum.rs
@@ -21,11 +21,12 @@ enum Foo {
     Bar,
 }
 
-extern "rust-intrinsic" {
-    #[stable(feature = "intrinsics_for_test", since = "3.3.3")]
-    #[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")]
-    #[rustc_safe_intrinsic]
-    fn size_of<T>() -> usize;
+#[stable(feature = "intrinsics_for_test", since = "3.3.3")]
+#[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+const fn size_of<T>() -> usize {
+    loop {}
 }
 
 #[lang="sized"]
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 6d49996c3b5e9..10c31d7943866 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -36,10 +36,4 @@ impl const Bar for Foo {
 pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
 //~^ ERROR function has missing const stability attribute
 
-extern "rust-intrinsic" {
-    #[stable(feature = "stable", since = "1.0.0")]
-    #[rustc_const_stable_indirect]
-    pub fn min_align_of_val<T>(x: *const T) -> usize;
-}
-
 fn main() {}
diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs
index 7f14d700ecba6..d62b86693c2ce 100644
--- a/tests/ui/target-feature/feature-hierarchy.rs
+++ b/tests/ui/target-feature/feature-hierarchy.rs
@@ -18,10 +18,12 @@ trait Sized {}
 trait Copy {}
 impl Copy for bool {}
 
-extern "rust-intrinsic" {
-    #[stable(feature = "test", since = "1.0.0")]
-    #[rustc_const_stable(feature = "test", since = "1.0.0")]
-    fn unreachable() -> !;
+#[stable(feature = "test", since = "1.0.0")]
+#[rustc_const_stable(feature = "test", since = "1.0.0")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+const unsafe fn unreachable() -> ! {
+    loop {}
 }
 
 #[rustc_builtin_macro]
diff --git a/tests/ui/target-feature/no-llvm-leaks.rs b/tests/ui/target-feature/no-llvm-leaks.rs
index f0c887bc1e0ff..102686864050a 100644
--- a/tests/ui/target-feature/no-llvm-leaks.rs
+++ b/tests/ui/target-feature/no-llvm-leaks.rs
@@ -16,10 +16,12 @@ trait Sized {}
 trait Copy {}
 impl Copy for bool {}
 
-extern "rust-intrinsic" {
-    #[stable(feature = "test", since = "1.0.0")]
-    #[rustc_const_stable(feature = "test", since = "1.0.0")]
-    fn unreachable() -> !;
+#[stable(feature = "test", since = "1.0.0")]
+#[rustc_const_stable(feature = "test", since = "1.0.0")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+const unsafe fn unreachable() -> ! {
+    loop {}
 }
 
 #[rustc_builtin_macro]