diff options
| -rw-r--r-- | compiler/rustc_codegen_cranelift/example/mini_core.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 4 | ||||
| -rw-r--r-- | library/core/src/any.rs | 4 | ||||
| -rw-r--r-- | library/core/src/intrinsics/mod.rs | 32 | ||||
| -rw-r--r-- | library/core/src/mem/mod.rs | 4 | ||||
| -rw-r--r-- | tests/ui-fulldeps/stable-mir/check_allocation.rs | 60 |
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() {{ |
