Skip to content

Commit 672e0be

Browse files
committed
Stop backends from needing to support nullary intrinsics
1 parent f191420 commit 672e0be

File tree

9 files changed

+67
-86
lines changed

9 files changed

+67
-86
lines changed

compiler/rustc_codegen_cranelift/example/mini_core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ pub mod intrinsics {
660660
#[rustc_intrinsic]
661661
pub unsafe fn ctlz_nonzero<T>(x: T) -> u32;
662662
#[rustc_intrinsic]
663-
pub fn needs_drop<T: ?::Sized>() -> bool;
663+
pub const fn needs_drop<T: ?::Sized>() -> bool;
664664
#[rustc_intrinsic]
665665
pub fn bitreverse<T>(x: T) -> T;
666666
#[rustc_intrinsic]

compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)]
1+
#![feature(
2+
no_core,
3+
lang_items,
4+
never_type,
5+
linkage,
6+
extern_types,
7+
thread_local,
8+
repr_simd,
9+
rustc_private
10+
)]
211
#![no_core]
312
#![allow(dead_code, non_camel_case_types, internal_features)]
413

@@ -207,10 +216,14 @@ fn main() {
207216
assert_eq!(intrinsics::align_of::<u16>() as u8, 2);
208217
assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8);
209218

210-
assert!(!intrinsics::needs_drop::<u8>());
211-
assert!(!intrinsics::needs_drop::<[u8]>());
212-
assert!(intrinsics::needs_drop::<NoisyDrop>());
213-
assert!(intrinsics::needs_drop::<NoisyDropUnsized>());
219+
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
220+
assert!(!u8_needs_drop);
221+
let slice_needs_drop = const { intrinsics::needs_drop::<[u8]>() };
222+
assert!(!slice_needs_drop);
223+
let noisy_drop = const { intrinsics::needs_drop::<NoisyDrop>() };
224+
assert!(noisy_drop);
225+
let noisy_unsized_drop = const { intrinsics::needs_drop::<NoisyDropUnsized>() };
226+
assert!(noisy_unsized_drop);
214227

215228
Unique { pointer: NonNull(1 as *mut &str), _marker: PhantomData } as Unique<dyn SomeTrait>;
216229

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -812,21 +812,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
812812
dest.write_cvalue(fx, val);
813813
}
814814

815-
sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
816-
intrinsic_args!(fx, args => (); intrinsic);
817-
818-
let const_val = fx
819-
.tcx
820-
.const_eval_instance(
821-
ty::TypingEnv::fully_monomorphized(),
822-
instance,
823-
source_info.span,
824-
)
825-
.unwrap();
826-
let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
827-
ret.write_cvalue(fx, val);
828-
}
829-
830815
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
831816
intrinsic_args!(fx, args => (ptr, base); intrinsic);
832817
let ptr = ptr.load_scalar(fx);

compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
)]
77
#![no_core]
88
#![allow(dead_code, internal_features, non_camel_case_types)]
9+
#![rustfmt::skip]
910

1011
extern crate mini_core;
1112

@@ -197,10 +198,10 @@ fn main() {
197198
assert_eq!(intrinsics::align_of::<u16>() as u8, 2);
198199
assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8);
199200

200-
assert!(!intrinsics::needs_drop::<u8>());
201-
assert!(!intrinsics::needs_drop::<[u8]>());
202-
assert!(intrinsics::needs_drop::<NoisyDrop>());
203-
assert!(intrinsics::needs_drop::<NoisyDropUnsized>());
201+
assert!(!const { intrinsics::needs_drop::<u8>() });
202+
assert!(!const { intrinsics::needs_drop::<[u8]>() });
203+
assert!(const { intrinsics::needs_drop::<NoisyDrop>() });
204+
assert!(const { intrinsics::needs_drop::<NoisyDropUnsized>() });
204205

205206
Unique {
206207
pointer: 0 as *const &str,

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
150150
}
151151
value
152152
}
153-
sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
154-
let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap();
155-
OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx)
156-
}
157153
sym::arith_offset => {
158154
let ty = fn_args.type_at(0);
159155
let layout = bx.layout_of(ty);

library/core/src/any.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ impl TypeId {
742742
#[stable(feature = "rust1", since = "1.0.0")]
743743
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
744744
pub const fn of<T: ?Sized + 'static>() -> TypeId {
745-
let t: u128 = intrinsics::type_id::<T>();
745+
let t: u128 = const { intrinsics::type_id::<T>() };
746746
let t1 = (t >> 64) as u64;
747747
let t2 = t as u64;
748748

@@ -824,7 +824,7 @@ impl fmt::Debug for TypeId {
824824
#[stable(feature = "type_name", since = "1.38.0")]
825825
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
826826
pub const fn type_name<T: ?Sized>() -> &'static str {
827-
intrinsics::type_name::<T>()
827+
const { intrinsics::type_name::<T>() }
828828
}
829829

830830
/// Returns the type name of the pointed-to value as a string slice.

library/core/src/intrinsics/mod.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,10 @@ pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
839839
/// If the actual type neither requires drop glue nor implements
840840
/// `Copy`, then the return value of this function is unspecified.
841841
///
842-
/// Note that, unlike most intrinsics, this is safe to call;
843-
/// it does not require an `unsafe` block.
844-
/// Therefore, implementations must not require the user to uphold
845-
/// any safety invariants.
842+
/// Note that, unlike most intrinsics, this can only be called at compile-time
843+
/// as backends do not have an implementation for it. The only caller (its
844+
/// stable counterpart), wraps this intrinsic call in a `const` block so that
845+
/// backends only see an evaluated constant.
846846
///
847847
/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
848848
#[rustc_intrinsic_const_stable_indirect]
@@ -2655,10 +2655,10 @@ pub const fn align_of<T>() -> usize;
26552655
/// Returns the number of variants of the type `T` cast to a `usize`;
26562656
/// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
26572657
///
2658-
/// Note that, unlike most intrinsics, this is safe to call;
2659-
/// it does not require an `unsafe` block.
2660-
/// Therefore, implementations must not require the user to uphold
2661-
/// any safety invariants.
2658+
/// Note that, unlike most intrinsics, this can only be called at compile-time
2659+
/// as backends do not have an implementation for it. The only caller (its
2660+
/// stable counterpart), wraps this intrinsic call in a `const` block so that
2661+
/// backends only see an evaluated constant.
26622662
///
26632663
/// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`].
26642664
#[rustc_nounwind]
@@ -2694,10 +2694,10 @@ pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
26942694

26952695
/// Gets a static string slice containing the name of a type.
26962696
///
2697-
/// Note that, unlike most intrinsics, this is safe to call;
2698-
/// it does not require an `unsafe` block.
2699-
/// Therefore, implementations must not require the user to uphold
2700-
/// any safety invariants.
2697+
/// Note that, unlike most intrinsics, this can only be called at compile-time
2698+
/// as backends do not have an implementation for it. The only caller (its
2699+
/// stable counterpart), wraps this intrinsic call in a `const` block so that
2700+
/// backends only see an evaluated constant.
27012701
///
27022702
/// The stabilized version of this intrinsic is [`core::any::type_name`].
27032703
#[rustc_nounwind]
@@ -2709,10 +2709,10 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
27092709
/// function will return the same value for a type regardless of whichever
27102710
/// crate it is invoked in.
27112711
///
2712-
/// Note that, unlike most intrinsics, this is safe to call;
2713-
/// it does not require an `unsafe` block.
2714-
/// Therefore, implementations must not require the user to uphold
2715-
/// any safety invariants.
2712+
/// Note that, unlike most intrinsics, this can only be called at compile-time
2713+
/// as backends do not have an implementation for it. The only caller (its
2714+
/// stable counterpart), wraps this intrinsic call in a `const` block so that
2715+
/// backends only see an evaluated constant.
27162716
///
27172717
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
27182718
#[rustc_nounwind]

library/core/src/mem/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
616616
#[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")]
617617
#[rustc_diagnostic_item = "needs_drop"]
618618
pub const fn needs_drop<T: ?Sized>() -> bool {
619-
intrinsics::needs_drop::<T>()
619+
const { intrinsics::needs_drop::<T>() }
620620
}
621621

622622
/// 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> {
12151215
#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
12161216
#[rustc_diagnostic_item = "mem_variant_count"]
12171217
pub const fn variant_count<T>() -> usize {
1218-
intrinsics::variant_count::<T>()
1218+
const { intrinsics::variant_count::<T>() }
12191219
}
12201220

12211221
/// Provides associated constants for various useful properties of types,

tests/ui-fulldeps/stable-mir/check_allocation.rs

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ extern crate rustc_driver;
1919
extern crate rustc_interface;
2020
extern crate stable_mir;
2121

22-
use stable_mir::crate_def::CrateDef;
23-
use stable_mir::mir::alloc::GlobalAlloc;
24-
use stable_mir::mir::mono::{Instance, InstanceKind, StaticDef};
25-
use stable_mir::mir::{Body, TerminatorKind};
26-
use stable_mir::ty::{Allocation, ConstantKind, RigidTy, TyKind};
27-
use stable_mir::{CrateItem, CrateItems, ItemKind};
2822
use std::ascii::Char;
2923
use std::assert_matches::assert_matches;
3024
use std::cmp::{max, min};
@@ -33,6 +27,13 @@ use std::ffi::CStr;
3327
use std::io::Write;
3428
use std::ops::ControlFlow;
3529

30+
use stable_mir::crate_def::CrateDef;
31+
use stable_mir::mir::Body;
32+
use stable_mir::mir::alloc::GlobalAlloc;
33+
use stable_mir::mir::mono::{Instance, StaticDef};
34+
use stable_mir::ty::{Allocation, ConstantKind};
35+
use stable_mir::{CrateItem, CrateItems, ItemKind};
36+
3637
const CRATE_NAME: &str = "input";
3738

3839
/// This function uses the Stable MIR APIs to get information about the test crate.
@@ -44,7 +45,6 @@ fn test_stable_mir() -> ControlFlow<()> {
4445
check_len(*get_item(&items, (ItemKind::Static, "LEN")).unwrap());
4546
check_cstr(*get_item(&items, (ItemKind::Static, "C_STR")).unwrap());
4647
check_other_consts(*get_item(&items, (ItemKind::Fn, "other_consts")).unwrap());
47-
check_type_id(*get_item(&items, (ItemKind::Fn, "check_type_id")).unwrap());
4848
ControlFlow::Continue(())
4949
}
5050

@@ -107,7 +107,9 @@ fn check_other_consts(item: CrateItem) {
107107
// Instance body will force constant evaluation.
108108
let body = Instance::try_from(item).unwrap().body().unwrap();
109109
let assigns = collect_consts(&body);
110-
assert_eq!(assigns.len(), 8);
110+
assert_eq!(assigns.len(), 10);
111+
let mut char_id = None;
112+
let mut bool_id = None;
111113
for (name, alloc) in assigns {
112114
match name.as_str() {
113115
"_max_u128" => {
@@ -149,35 +151,21 @@ fn check_other_consts(item: CrateItem) {
149151
assert_eq!(max(first, second) as u32, u32::MAX);
150152
assert_eq!(min(first, second), 10);
151153
}
154+
"_bool_id" => {
155+
bool_id = Some(alloc);
156+
}
157+
"_char_id" => {
158+
char_id = Some(alloc);
159+
}
152160
_ => {
153161
unreachable!("{name} -- {alloc:?}")
154162
}
155163
}
156164
}
157-
}
158-
159-
/// Check that we can retrieve the type id of char and bool, and that they have different values.
160-
fn check_type_id(item: CrateItem) {
161-
let body = Instance::try_from(item).unwrap().body().unwrap();
162-
let mut ids: Vec<u128> = vec![];
163-
for term in body.blocks.iter().map(|bb| &bb.terminator) {
164-
match &term.kind {
165-
TerminatorKind::Call { func, destination, .. } => {
166-
let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else {
167-
unreachable!()
168-
};
169-
let RigidTy::FnDef(def, args) = ty else { unreachable!() };
170-
let instance = Instance::resolve(def, &args).unwrap();
171-
assert_eq!(instance.kind, InstanceKind::Intrinsic);
172-
let dest_ty = destination.ty(body.locals()).unwrap();
173-
let alloc = instance.try_const_eval(dest_ty).unwrap();
174-
ids.push(alloc.read_uint().unwrap());
175-
}
176-
_ => { /* Do nothing */ }
177-
}
178-
}
179-
assert_eq!(ids.len(), 2);
180-
assert_ne!(ids[0], ids[1]);
165+
let bool_id = bool_id.unwrap();
166+
let char_id = char_id.unwrap();
167+
// FIXME(stable_mir): add `read_ptr` to `Allocation`
168+
assert_ne!(bool_id, char_id);
181169
}
182170

183171
/// Collects all the constant assignments.
@@ -235,6 +223,7 @@ fn generate_input(path: &str) -> std::io::Result<()> {
235223
file,
236224
r#"
237225
#![feature(core_intrinsics)]
226+
#![expect(internal_features)]
238227
use std::intrinsics::type_id;
239228
240229
static LEN: usize = 2;
@@ -254,11 +243,8 @@ fn generate_input(path: &str) -> std::io::Result<()> {
254243
let _ptr = &BAR;
255244
let _null_ptr: *const u8 = NULL;
256245
let _tuple = TUPLE;
257-
}}
258-
259-
fn check_type_id() {{
260-
let _char_id = type_id::<char>();
261-
let _bool_id = type_id::<bool>();
246+
let _char_id = const {{ type_id::<char>() }};
247+
let _bool_id = const {{ type_id::<bool>() }};
262248
}}
263249
264250
pub fn main() {{

0 commit comments

Comments
 (0)