about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs23
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs15
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs4
-rw-r--r--library/core/src/any.rs4
-rw-r--r--library/core/src/intrinsics/mod.rs32
-rw-r--r--library/core/src/mem/mod.rs4
-rw-r--r--tests/ui-fulldeps/stable-mir/check_allocation.rs60
9 files changed, 67 insertions, 86 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 524ebde1c74..2f53bbf8b79 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -660,7 +660,7 @@ pub mod intrinsics {
     #[rustc_intrinsic]
     pub unsafe fn ctlz_nonzero<T>(x: T) -> u32;
     #[rustc_intrinsic]
-    pub fn needs_drop<T: ?::Sized>() -> bool;
+    pub const fn needs_drop<T: ?::Sized>() -> bool;
     #[rustc_intrinsic]
     pub fn bitreverse<T>(x: T) -> T;
     #[rustc_intrinsic]
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index 1499f948deb..246bd3104ec 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -1,4 +1,13 @@
-#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)]
+#![feature(
+    no_core,
+    lang_items,
+    never_type,
+    linkage,
+    extern_types,
+    thread_local,
+    repr_simd,
+    rustc_private
+)]
 #![no_core]
 #![allow(dead_code, non_camel_case_types, internal_features)]
 
@@ -207,10 +216,14 @@ fn main() {
         assert_eq!(intrinsics::align_of::<u16>() as u8, 2);
         assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8);
 
-        assert!(!intrinsics::needs_drop::<u8>());
-        assert!(!intrinsics::needs_drop::<[u8]>());
-        assert!(intrinsics::needs_drop::<NoisyDrop>());
-        assert!(intrinsics::needs_drop::<NoisyDropUnsized>());
+        let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
+        assert!(!u8_needs_drop);
+        let slice_needs_drop = const { intrinsics::needs_drop::<[u8]>() };
+        assert!(!slice_needs_drop);
+        let noisy_drop = const { intrinsics::needs_drop::<NoisyDrop>() };
+        assert!(noisy_drop);
+        let noisy_unsized_drop = const { intrinsics::needs_drop::<NoisyDropUnsized>() };
+        assert!(noisy_unsized_drop);
 
         Unique { pointer: NonNull(1 as *mut &str), _marker: PhantomData } as Unique<dyn SomeTrait>;
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index df5748c34d1..4ff5773a06c 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -812,21 +812,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
             dest.write_cvalue(fx, val);
         }
 
-        sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
-            intrinsic_args!(fx, args => (); intrinsic);
-
-            let const_val = fx
-                .tcx
-                .const_eval_instance(
-                    ty::TypingEnv::fully_monomorphized(),
-                    instance,
-                    source_info.span,
-                )
-                .unwrap();
-            let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
-            ret.write_cvalue(fx, val);
-        }
-
         sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
             intrinsic_args!(fx, args => (ptr, base); intrinsic);
             let ptr = ptr.load_scalar(fx);
diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
index c3bd62e5897..6b6f71edaf8 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
@@ -6,6 +6,7 @@
 )]
 #![no_core]
 #![allow(dead_code, internal_features, non_camel_case_types)]
+#![rustfmt::skip]
 
 extern crate mini_core;
 
@@ -197,10 +198,10 @@ fn main() {
         assert_eq!(intrinsics::align_of::<u16>() as u8, 2);
         assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8);
 
-        assert!(!intrinsics::needs_drop::<u8>());
-        assert!(!intrinsics::needs_drop::<[u8]>());
-        assert!(intrinsics::needs_drop::<NoisyDrop>());
-        assert!(intrinsics::needs_drop::<NoisyDropUnsized>());
+        assert!(!const { intrinsics::needs_drop::<u8>() });
+        assert!(!const { intrinsics::needs_drop::<[u8]>() });
+        assert!(const { intrinsics::needs_drop::<NoisyDrop>() });
+        assert!(const { intrinsics::needs_drop::<NoisyDropUnsized>() });
 
         Unique {
             pointer: 0 as *const &str,
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 27fcab8ed2d..f77c8e500cc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -150,10 +150,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
                 value
             }
-            sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
-                let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap();
-                OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx)
-            }
             sym::arith_offset => {
                 let ty = fn_args.type_at(0);
                 let layout = bx.layout_of(ty);
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 7aa3f3c6d74..01dce114592 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -742,7 +742,7 @@ impl TypeId {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
     pub const fn of<T: ?Sized + 'static>() -> TypeId {
-        let t: u128 = intrinsics::type_id::<T>();
+        let t: u128 = const { intrinsics::type_id::<T>() };
         let t1 = (t >> 64) as u64;
         let t2 = t as u64;
 
@@ -824,7 +824,7 @@ impl fmt::Debug for TypeId {
 #[stable(feature = "type_name", since = "1.38.0")]
 #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
 pub const fn type_name<T: ?Sized>() -> &'static str {
-    intrinsics::type_name::<T>()
+    const { intrinsics::type_name::<T>() }
 }
 
 /// Returns the type name of the pointed-to value as a string slice.
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index b5c3e91d046..47dd7c7aefd 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -839,10 +839,10 @@ pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
 /// 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.
+/// Note that, unlike most intrinsics, this can only be called at compile-time
+/// as backends do not have an implementation for it. The only caller (its
+/// stable counterpart), wraps this intrinsic call in a `const` block so that
+/// backends only see an evaluated constant.
 ///
 /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
 #[rustc_intrinsic_const_stable_indirect]
@@ -2655,10 +2655,10 @@ pub const fn align_of<T>() -> usize;
 /// Returns the number of variants of the type `T` cast to a `usize`;
 /// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
 ///
-/// 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.
+/// Note that, unlike most intrinsics, this can only be called at compile-time
+/// as backends do not have an implementation for it. The only caller (its
+/// stable counterpart), wraps this intrinsic call in a `const` block so that
+/// backends only see an evaluated constant.
 ///
 /// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`].
 #[rustc_nounwind]
@@ -2694,10 +2694,10 @@ pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
 
 /// Gets a static string slice containing the name of a type.
 ///
-/// 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.
+/// Note that, unlike most intrinsics, this can only be called at compile-time
+/// as backends do not have an implementation for it. The only caller (its
+/// stable counterpart), wraps this intrinsic call in a `const` block so that
+/// backends only see an evaluated constant.
 ///
 /// The stabilized version of this intrinsic is [`core::any::type_name`].
 #[rustc_nounwind]
@@ -2709,10 +2709,10 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
 /// function will return the same value for a type regardless of whichever
 /// crate it is invoked in.
 ///
-/// 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.
+/// Note that, unlike most intrinsics, this can only be called at compile-time
+/// as backends do not have an implementation for it. The only caller (its
+/// stable counterpart), wraps this intrinsic call in a `const` block so that
+/// backends only see an evaluated constant.
 ///
 /// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
 #[rustc_nounwind]
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index b93f854b9dc..c00585de064 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -616,7 +616,7 @@ pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
 #[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")]
 #[rustc_diagnostic_item = "needs_drop"]
 pub const fn needs_drop<T: ?Sized>() -> bool {
-    intrinsics::needs_drop::<T>()
+    const { intrinsics::needs_drop::<T>() }
 }
 
 /// Returns the value of type `T` represented by the all-zero byte-pattern.
@@ -1215,7 +1215,7 @@ pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
 #[rustc_const_unstable(feature = "variant_count", issue = "73662")]
 #[rustc_diagnostic_item = "mem_variant_count"]
 pub const fn variant_count<T>() -> usize {
-    intrinsics::variant_count::<T>()
+    const { intrinsics::variant_count::<T>() }
 }
 
 /// Provides associated constants for various useful properties of types,
diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs
index 692c24f0544..64194e72888 100644
--- a/tests/ui-fulldeps/stable-mir/check_allocation.rs
+++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs
@@ -19,12 +19,6 @@ extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate stable_mir;
 
-use stable_mir::crate_def::CrateDef;
-use stable_mir::mir::alloc::GlobalAlloc;
-use stable_mir::mir::mono::{Instance, InstanceKind, StaticDef};
-use stable_mir::mir::{Body, TerminatorKind};
-use stable_mir::ty::{Allocation, ConstantKind, RigidTy, TyKind};
-use stable_mir::{CrateItem, CrateItems, ItemKind};
 use std::ascii::Char;
 use std::assert_matches::assert_matches;
 use std::cmp::{max, min};
@@ -33,6 +27,13 @@ use std::ffi::CStr;
 use std::io::Write;
 use std::ops::ControlFlow;
 
+use stable_mir::crate_def::CrateDef;
+use stable_mir::mir::Body;
+use stable_mir::mir::alloc::GlobalAlloc;
+use stable_mir::mir::mono::{Instance, StaticDef};
+use stable_mir::ty::{Allocation, ConstantKind};
+use stable_mir::{CrateItem, CrateItems, ItemKind};
+
 const CRATE_NAME: &str = "input";
 
 /// This function uses the Stable MIR APIs to get information about the test crate.
@@ -44,7 +45,6 @@ fn test_stable_mir() -> ControlFlow<()> {
     check_len(*get_item(&items, (ItemKind::Static, "LEN")).unwrap());
     check_cstr(*get_item(&items, (ItemKind::Static, "C_STR")).unwrap());
     check_other_consts(*get_item(&items, (ItemKind::Fn, "other_consts")).unwrap());
-    check_type_id(*get_item(&items, (ItemKind::Fn, "check_type_id")).unwrap());
     ControlFlow::Continue(())
 }
 
@@ -107,7 +107,9 @@ fn check_other_consts(item: CrateItem) {
     // Instance body will force constant evaluation.
     let body = Instance::try_from(item).unwrap().body().unwrap();
     let assigns = collect_consts(&body);
-    assert_eq!(assigns.len(), 8);
+    assert_eq!(assigns.len(), 10);
+    let mut char_id = None;
+    let mut bool_id = None;
     for (name, alloc) in assigns {
         match name.as_str() {
             "_max_u128" => {
@@ -149,35 +151,21 @@ fn check_other_consts(item: CrateItem) {
                 assert_eq!(max(first, second) as u32, u32::MAX);
                 assert_eq!(min(first, second), 10);
             }
+            "_bool_id" => {
+                bool_id = Some(alloc);
+            }
+            "_char_id" => {
+                char_id = Some(alloc);
+            }
             _ => {
                 unreachable!("{name} -- {alloc:?}")
             }
         }
     }
-}
-
-/// Check that we can retrieve the type id of char and bool, and that they have different values.
-fn check_type_id(item: CrateItem) {
-    let body = Instance::try_from(item).unwrap().body().unwrap();
-    let mut ids: Vec<u128> = vec![];
-    for term in body.blocks.iter().map(|bb| &bb.terminator) {
-        match &term.kind {
-            TerminatorKind::Call { func, destination, .. } => {
-                let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else {
-                    unreachable!()
-                };
-                let RigidTy::FnDef(def, args) = ty else { unreachable!() };
-                let instance = Instance::resolve(def, &args).unwrap();
-                assert_eq!(instance.kind, InstanceKind::Intrinsic);
-                let dest_ty = destination.ty(body.locals()).unwrap();
-                let alloc = instance.try_const_eval(dest_ty).unwrap();
-                ids.push(alloc.read_uint().unwrap());
-            }
-            _ => { /* Do nothing */ }
-        }
-    }
-    assert_eq!(ids.len(), 2);
-    assert_ne!(ids[0], ids[1]);
+    let bool_id = bool_id.unwrap();
+    let char_id = char_id.unwrap();
+    // FIXME(stable_mir): add `read_ptr` to `Allocation`
+    assert_ne!(bool_id, char_id);
 }
 
 /// Collects all the constant assignments.
@@ -235,6 +223,7 @@ fn generate_input(path: &str) -> std::io::Result<()> {
         file,
         r#"
     #![feature(core_intrinsics)]
+    #![expect(internal_features)]
     use std::intrinsics::type_id;
 
     static LEN: usize = 2;
@@ -254,11 +243,8 @@ fn generate_input(path: &str) -> std::io::Result<()> {
         let _ptr = &BAR;
         let _null_ptr: *const u8 = NULL;
         let _tuple = TUPLE;
-    }}
-
-    fn check_type_id() {{
-        let _char_id = type_id::<char>();
-        let _bool_id = type_id::<bool>();
+        let _char_id = const {{ type_id::<char>() }};
+        let _bool_id = const {{ type_id::<bool>() }};
     }}
 
     pub fn main() {{