Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f670fb1

Browse files
committedApr 22, 2024·
Add an intrinsic for ptr::metadata
1 parent fb89862 commit f670fb1

25 files changed

+407
-43
lines changed
 

‎compiler/rustc_borrowck/src/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2398,11 +2398,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23982398
}
23992399
}
24002400
}
2401-
CastKind::Transmute => {
2401+
CastKind::PtrToMetadata | CastKind::Transmute => {
24022402
span_mirbug!(
24032403
self,
24042404
rvalue,
2405-
"Unexpected CastKind::Transmute, which is not permitted in Analysis MIR",
2405+
"Unexpected CastKind::{cast_kind:?}, which is not permitted in Analysis MIR",
24062406
);
24072407
}
24082408
}

‎compiler/rustc_codegen_cranelift/src/base.rs

+11
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,17 @@ fn codegen_stmt<'tcx>(
698698
lval.write_cvalue(fx, CValue::by_val(res, dest_layout));
699699
}
700700
}
701+
Rvalue::Cast(CastKind::PtrToMetadata, ref operand, _to_ty) => {
702+
let operand = codegen_operand(fx, operand);
703+
let meta = match operand.layout().abi {
704+
Abi::Scalar(_) => CValue::zst(dest_layout),
705+
Abi::ScalarPair(_, _) => {
706+
CValue::by_val(operand.load_scalar_pair(fx).1, dest_layout)
707+
}
708+
_ => bug!("Unexpected `PtrToMetadata` operand: {operand:?}"),
709+
};
710+
lval.write_cvalue(fx, meta);
711+
}
701712
Rvalue::Cast(
702713
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
703714
ref operand,

‎compiler/rustc_codegen_cranelift/src/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub(crate) fn codegen_const_value<'tcx>(
100100
assert!(layout.is_sized(), "unsized const value");
101101

102102
if layout.is_zst() {
103-
return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout);
103+
return CValue::zst(layout);
104104
}
105105

106106
match const_val {

‎compiler/rustc_codegen_cranelift/src/value_and_place.rs

+8
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ impl<'tcx> CValue<'tcx> {
111111
CValue(inner, layout)
112112
}
113113

114+
/// Create an instance of a ZST
115+
///
116+
/// The is represented by a dangling pointer of suitable alignment.
117+
pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> {
118+
assert!(layout.is_zst());
119+
CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout)
120+
}
121+
114122
pub(crate) fn layout(&self) -> TyAndLayout<'tcx> {
115123
self.1
116124
}

‎compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+7
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
565565
};
566566
OperandValue::Immediate(newval)
567567
}
568+
mir::CastKind::PtrToMetadata => {
569+
match operand.val {
570+
OperandValue::Immediate(_) => OperandValue::ZeroSized,
571+
OperandValue::Pair(_, meta) => OperandValue::Immediate(meta),
572+
_ => bug!("Unexpected operand to `PtrToMetadata`: {operand:?}"),
573+
}
574+
}
568575
mir::CastKind::Transmute => {
569576
self.codegen_transmute_operand(bx, operand, cast).unwrap_or_else(|| {
570577
bug!("Unsupported transmute-as-operand of {operand:?} to {cast:?}");

‎compiler/rustc_const_eval/src/interpret/cast.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6464
self.write_immediate(*res, dest)?;
6565
}
6666

67+
CastKind::PtrToMetadata => {
68+
let src = self.read_immediate(src)?;
69+
let res = self.ptr_to_metadata(&src, cast_layout)?;
70+
self.write_immediate(*res, dest)?;
71+
}
72+
6773
CastKind::PointerCoercion(
6874
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
6975
) => {
@@ -204,7 +210,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
204210
assert!(cast_to.ty.is_unsafe_ptr());
205211
// Handle casting any ptr to raw ptr (might be a fat ptr).
206212
if cast_to.size == src.layout.size {
207-
// Thin or fat pointer that just hast the ptr kind of target type changed.
213+
// Thin or fat pointer that just has the ptr kind of target type changed.
208214
return Ok(ImmTy::from_immediate(**src, cast_to));
209215
} else {
210216
// Casting the metadata away from a fat ptr.
@@ -225,6 +231,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
225231
}
226232
}
227233

234+
fn ptr_to_metadata(
235+
&self,
236+
src: &ImmTy<'tcx, M::Provenance>,
237+
cast_to: TyAndLayout<'tcx>,
238+
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
239+
assert!(src.layout.ty.is_unsafe_ptr());
240+
return Ok(match **src {
241+
Immediate::Scalar(_) => {
242+
assert!(cast_to.is_zst());
243+
ImmTy::uninit(cast_to)
244+
}
245+
Immediate::ScalarPair(_, meta) => ImmTy::from_scalar(meta, cast_to),
246+
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
247+
});
248+
}
249+
228250
pub fn pointer_expose_provenance_cast(
229251
&mut self,
230252
src: &ImmTy<'tcx, M::Provenance>,

‎compiler/rustc_const_eval/src/transform/validate.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11351135
self.fail(location, "Can't cast {op_ty} into 'Ptr'");
11361136
}
11371137
}
1138+
CastKind::PtrToMetadata => {
1139+
if !op_ty.is_unsafe_ptr() {
1140+
self.fail(location, "Can't get ptr metadata from {op_ty}");
1141+
}
1142+
let pointee_ty = op_ty.builtin_deref(true).unwrap().ty;
1143+
1144+
// FIXME: Check metadata more generally
1145+
if pointee_ty.is_slice() {
1146+
if !self.mir_assign_valid_types(*target_type, self.tcx.types.usize) {
1147+
self.fail(location, "slice metadata must be usize");
1148+
}
1149+
} else if pointee_ty.is_sized(self.tcx, self.param_env) {
1150+
if *target_type != self.tcx.types.unit {
1151+
self.fail(location, "metadata for pointer-to-thin must be unit");
1152+
}
1153+
}
1154+
}
11381155
CastKind::FloatToFloat | CastKind::FloatToInt => {
11391156
if !op_ty.is_floating_point() || !target_type.is_numeric() {
11401157
self.fail(

‎compiler/rustc_hir_analysis/src/check/intrinsic.rs

+2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
129129
| sym::is_val_statically_known
130130
| sym::ptr_mask
131131
| sym::aggregate_raw_ptr
132+
| sym::ptr_metadata
132133
| sym::ub_checks
133134
| sym::fadd_algebraic
134135
| sym::fsub_algebraic
@@ -578,6 +579,7 @@ pub fn check_intrinsic_type(
578579
// This type check is not particularly useful, but the `where` bounds
579580
// on the definition in `core` do the heavy lifting for checking it.
580581
sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)),
582+
sym::ptr_metadata => (2, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
581583

582584
sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
583585

‎compiler/rustc_middle/src/mir/statement.rs

+1
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ impl<'tcx> Rvalue<'tcx> {
425425
| CastKind::IntToFloat
426426
| CastKind::FnPtrToPtr
427427
| CastKind::PtrToPtr
428+
| CastKind::PtrToMetadata
428429
| CastKind::PointerCoercion(_)
429430
| CastKind::PointerWithExposedProvenance
430431
| CastKind::DynStar

‎compiler/rustc_middle/src/mir/syntax.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,17 @@ pub enum CastKind {
13251325
IntToFloat,
13261326
PtrToPtr,
13271327
FnPtrToPtr,
1328+
/// Convert a raw pointer to an `impl Pointee<Metadata = M>` into `M`.
1329+
///
1330+
/// For example, this will give a `()` from `*const i32`, a `usize` from
1331+
/// `*mut [u8]`, or a vtable from a `*const dyn Foo`.
1332+
///
1333+
/// There's only one legal cast type based on the input type, but calculating
1334+
/// that type is expensive, and thus it's convenient for this to be a `Cast`
1335+
/// instead of an `UnOp`.
1336+
///
1337+
/// Allowed only in [`MirPhase::Runtime`]; Earlier it's an intrinsic.
1338+
PtrToMetadata,
13281339
/// Reinterpret the bits of the input as a different type.
13291340
///
13301341
/// MIR is well-formed if the input and output types have different sizes,

‎compiler/rustc_mir_transform/src/lower_intrinsics.rs

+18
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,24 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
315315

316316
terminator.kind = TerminatorKind::Goto { target };
317317
}
318+
sym::ptr_metadata => {
319+
let Ok([ptr]) = <[_; 1]>::try_from(std::mem::take(args)) else {
320+
span_bug!(
321+
terminator.source_info.span,
322+
"Wrong number of arguments for ptr_metadata intrinsic",
323+
);
324+
};
325+
let target = target.unwrap();
326+
let metadata_ty = generic_args.type_at(1);
327+
block.statements.push(Statement {
328+
source_info: terminator.source_info,
329+
kind: StatementKind::Assign(Box::new((
330+
*destination,
331+
Rvalue::Cast(CastKind::PtrToMetadata, ptr.node, metadata_ty),
332+
))),
333+
});
334+
terminator.kind = TerminatorKind::Goto { target };
335+
}
318336
_ => {}
319337
}
320338
}

‎compiler/rustc_smir/src/rustc_smir/convert/mir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
276276
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
277277
IntToFloat => stable_mir::mir::CastKind::IntToFloat,
278278
PtrToPtr => stable_mir::mir::CastKind::PtrToPtr,
279+
PtrToMetadata => stable_mir::mir::CastKind::PtrToMetadata,
279280
FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr,
280281
Transmute => stable_mir::mir::CastKind::Transmute,
281282
}

‎compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,7 @@ symbols! {
14171417
ptr_guaranteed_cmp,
14181418
ptr_is_null,
14191419
ptr_mask,
1420+
ptr_metadata,
14201421
ptr_null,
14211422
ptr_null_mut,
14221423
ptr_offset_from,

‎compiler/stable_mir/src/mir/body.rs

+1
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ pub enum CastKind {
949949
FloatToFloat,
950950
IntToFloat,
951951
PtrToPtr,
952+
PtrToMetadata,
952953
FnPtrToPtr,
953954
Transmute,
954955
}

‎library/core/src/intrinsics.rs

+15
Original file line numberDiff line numberDiff line change
@@ -2807,6 +2807,21 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
28072807
type Metadata = <P as ptr::Pointee>::Metadata;
28082808
}
28092809

2810+
/// Lowers in MIR to `Rvalue::Cast` with `CastKind::PtrToMetadata`.
2811+
///
2812+
/// This is used to implement functions like `ptr::metadata`.
2813+
#[rustc_nounwind]
2814+
#[unstable(feature = "core_intrinsics", issue = "none")]
2815+
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
2816+
#[rustc_intrinsic]
2817+
#[rustc_intrinsic_must_be_overridden]
2818+
#[cfg(not(bootstrap))]
2819+
pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *const P) -> M {
2820+
// To implement a fallback we'd have to assume the layout of the pointer,
2821+
// but the whole point of this intrinsic is that we shouldn't do that.
2822+
unreachable!()
2823+
}
2824+
28102825
// Some functions are defined here because they accidentally got made
28112826
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
28122827
// (`transmute` also falls into this category, but it cannot be wrapped due to the

‎library/core/src/ptr/metadata.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::fmt;
44
use crate::hash::{Hash, Hasher};
55
#[cfg(not(bootstrap))]
6-
use crate::intrinsics::aggregate_raw_ptr;
6+
use crate::intrinsics::{aggregate_raw_ptr, ptr_metadata};
77
use crate::marker::Freeze;
88

99
/// Provides the pointer metadata type of any pointed-to type.
@@ -95,10 +95,17 @@ pub trait Thin = Pointee<Metadata = ()>;
9595
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
9696
#[inline]
9797
pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
98-
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
99-
// and PtrComponents<T> have the same memory layouts. Only std can make this
100-
// guarantee.
101-
unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
98+
#[cfg(bootstrap)]
99+
{
100+
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
101+
// and PtrComponents<T> have the same memory layouts. Only std can make this
102+
// guarantee.
103+
unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
104+
}
105+
#[cfg(not(bootstrap))]
106+
{
107+
ptr_metadata(ptr)
108+
}
102109
}
103110

104111
/// Forms a (possibly-wide) raw pointer from a data pointer and metadata.
@@ -153,22 +160,26 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
153160
}
154161

155162
#[repr(C)]
163+
#[cfg(bootstrap)]
156164
union PtrRepr<T: ?Sized> {
157165
const_ptr: *const T,
158166
mut_ptr: *mut T,
159167
components: PtrComponents<T>,
160168
}
161169

162170
#[repr(C)]
171+
#[cfg(bootstrap)]
163172
struct PtrComponents<T: ?Sized> {
164173
data_pointer: *const (),
165174
metadata: <T as Pointee>::Metadata,
166175
}
167176

168177
// Manual impl needed to avoid `T: Copy` bound.
178+
#[cfg(bootstrap)]
169179
impl<T: ?Sized> Copy for PtrComponents<T> {}
170180

171181
// Manual impl needed to avoid `T: Clone` bound.
182+
#[cfg(bootstrap)]
172183
impl<T: ?Sized> Clone for PtrComponents<T> {
173184
fn clone(&self) -> Self {
174185
*self

‎library/core/tests/ptr.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1171,3 +1171,11 @@ fn test_ptr_from_raw_parts_in_const() {
11711171
assert_eq!(EMPTY_SLICE_PTR.addr(), 123);
11721172
assert_eq!(EMPTY_SLICE_PTR.len(), 456);
11731173
}
1174+
1175+
#[test]
1176+
fn test_ptr_metadata_in_const() {
1177+
const ARRAY_META: () = std::ptr::metadata::<[u16; 3]>(&[1, 2, 3]);
1178+
const SLICE_META: usize = std::ptr::metadata::<[u16]>(&[1, 2, 3]);
1179+
assert_eq!(ARRAY_META, ());
1180+
assert_eq!(SLICE_META, 3);
1181+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//@ compile-flags: -O -C no-prepopulate-passes -Z inline-mir
2+
//@ only-64bit (so I don't need to worry about usize)
3+
4+
#![crate_type = "lib"]
5+
#![feature(core_intrinsics)]
6+
7+
use std::intrinsics::ptr_metadata;
8+
9+
// CHECK-LABEL: @thin_metadata(
10+
#[no_mangle]
11+
pub fn thin_metadata(p: *const ()) {
12+
// CHECK: start
13+
// CHECK-NEXT: ret void
14+
ptr_metadata(p)
15+
}
16+
17+
// CHECK-LABEL: @slice_metadata(
18+
#[no_mangle]
19+
pub fn slice_metadata(p: *const [u8]) -> usize {
20+
// CHECK: start
21+
// CHECK-NEXT: ret i64 %p.1
22+
ptr_metadata(p)
23+
}
24+
25+
// CHECK-LABEL: @dyn_byte_offset(
26+
#[no_mangle]
27+
pub unsafe fn dyn_byte_offset(p: *const dyn std::fmt::Debug, n: usize) -> *const dyn std::fmt::Debug {
28+
// CHECK: %[[Q:.+]] = getelementptr inbounds i8, ptr %p.0, i64 %n
29+
// CHECK: %[[TEMP1:.+]] = insertvalue { ptr, ptr } poison, ptr %[[Q]], 0
30+
// CHECK: %[[TEMP2:.+]] = insertvalue { ptr, ptr } %[[TEMP1]], ptr %p.1, 1
31+
// CHECK: ret { ptr, ptr } %[[TEMP2]]
32+
p.byte_add(n)
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
- // MIR for `get_metadata` before LowerIntrinsics
2+
+ // MIR for `get_metadata` after LowerIntrinsics
3+
4+
fn get_metadata(_1: *const i32, _2: *const [u8], _3: *const dyn Debug) -> () {
5+
debug a => _1;
6+
debug b => _2;
7+
debug c => _3;
8+
let mut _0: ();
9+
let _4: ();
10+
let mut _5: *const i32;
11+
let mut _7: *const [u8];
12+
let mut _9: *const dyn std::fmt::Debug;
13+
scope 1 {
14+
debug _unit => _4;
15+
let _6: usize;
16+
scope 2 {
17+
debug _usize => _6;
18+
let _8: std::ptr::DynMetadata<dyn std::fmt::Debug>;
19+
scope 3 {
20+
debug _vtable => _8;
21+
}
22+
}
23+
}
24+
25+
bb0: {
26+
StorageLive(_4);
27+
StorageLive(_5);
28+
_5 = _1;
29+
- _4 = ptr_metadata::<i32, ()>(move _5) -> [return: bb1, unwind unreachable];
30+
+ _4 = move _5 as () (PtrToMetadata);
31+
+ goto -> bb1;
32+
}
33+
34+
bb1: {
35+
StorageDead(_5);
36+
StorageLive(_6);
37+
StorageLive(_7);
38+
_7 = _2;
39+
- _6 = ptr_metadata::<[u8], usize>(move _7) -> [return: bb2, unwind unreachable];
40+
+ _6 = move _7 as usize (PtrToMetadata);
41+
+ goto -> bb2;
42+
}
43+
44+
bb2: {
45+
StorageDead(_7);
46+
StorageLive(_8);
47+
StorageLive(_9);
48+
_9 = _3;
49+
- _8 = ptr_metadata::<dyn Debug, DynMetadata<dyn Debug>>(move _9) -> [return: bb3, unwind unreachable];
50+
+ _8 = move _9 as std::ptr::DynMetadata<dyn std::fmt::Debug> (PtrToMetadata);
51+
+ goto -> bb3;
52+
}
53+
54+
bb3: {
55+
StorageDead(_9);
56+
_0 = const ();
57+
StorageDead(_8);
58+
StorageDead(_6);
59+
StorageDead(_4);
60+
return;
61+
}
62+
}
63+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
- // MIR for `get_metadata` before LowerIntrinsics
2+
+ // MIR for `get_metadata` after LowerIntrinsics
3+
4+
fn get_metadata(_1: *const i32, _2: *const [u8], _3: *const dyn Debug) -> () {
5+
debug a => _1;
6+
debug b => _2;
7+
debug c => _3;
8+
let mut _0: ();
9+
let _4: ();
10+
let mut _5: *const i32;
11+
let mut _7: *const [u8];
12+
let mut _9: *const dyn std::fmt::Debug;
13+
scope 1 {
14+
debug _unit => _4;
15+
let _6: usize;
16+
scope 2 {
17+
debug _usize => _6;
18+
let _8: std::ptr::DynMetadata<dyn std::fmt::Debug>;
19+
scope 3 {
20+
debug _vtable => _8;
21+
}
22+
}
23+
}
24+
25+
bb0: {
26+
StorageLive(_4);
27+
StorageLive(_5);
28+
_5 = _1;
29+
- _4 = ptr_metadata::<i32, ()>(move _5) -> [return: bb1, unwind unreachable];
30+
+ _4 = move _5 as () (PtrToMetadata);
31+
+ goto -> bb1;
32+
}
33+
34+
bb1: {
35+
StorageDead(_5);
36+
StorageLive(_6);
37+
StorageLive(_7);
38+
_7 = _2;
39+
- _6 = ptr_metadata::<[u8], usize>(move _7) -> [return: bb2, unwind unreachable];
40+
+ _6 = move _7 as usize (PtrToMetadata);
41+
+ goto -> bb2;
42+
}
43+
44+
bb2: {
45+
StorageDead(_7);
46+
StorageLive(_8);
47+
StorageLive(_9);
48+
_9 = _3;
49+
- _8 = ptr_metadata::<dyn Debug, DynMetadata<dyn Debug>>(move _9) -> [return: bb3, unwind unreachable];
50+
+ _8 = move _9 as std::ptr::DynMetadata<dyn std::fmt::Debug> (PtrToMetadata);
51+
+ goto -> bb3;
52+
}
53+
54+
bb3: {
55+
StorageDead(_9);
56+
_0 = const ();
57+
StorageDead(_8);
58+
StorageDead(_6);
59+
StorageDead(_4);
60+
return;
61+
}
62+
}
63+

‎tests/mir-opt/lower_intrinsics.rs

+9
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,12 @@ pub fn make_pointers(a: *const u8, b: *mut (), n: usize) {
258258
let _slice_const: *const [u16] = aggregate_raw_ptr(a, n);
259259
let _slice_mut: *mut [u64] = aggregate_raw_ptr(b, n);
260260
}
261+
262+
// EMIT_MIR lower_intrinsics.get_metadata.LowerIntrinsics.diff
263+
pub fn get_metadata(a: *const i32, b: *const [u8], c: *const dyn std::fmt::Debug) {
264+
use std::intrinsics::ptr_metadata;
265+
266+
let _unit = ptr_metadata(a);
267+
let _usize = ptr_metadata(b);
268+
let _vtable = ptr_metadata(c);
269+
}

‎tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir

+3-7
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
1313
}
1414
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
1515
let mut _5: *const ();
16-
let mut _7: usize;
16+
let mut _6: usize;
1717
scope 5 (inlined std::ptr::metadata::<[u32]>) {
18-
let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
1918
}
2019
scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
2120
}
@@ -30,13 +29,10 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
3029
StorageDead(_3);
3130
StorageLive(_5);
3231
_5 = _4 as *const () (PtrToPtr);
33-
StorageLive(_7);
3432
StorageLive(_6);
35-
_6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
36-
_7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
33+
_6 = _1 as usize (PtrToMetadata);
34+
_0 = *const [u32] from (_5, _6);
3735
StorageDead(_6);
38-
_0 = *const [u32] from (_5, _7);
39-
StorageDead(_7);
4036
StorageDead(_5);
4137
StorageDead(_4);
4238
return;

‎tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir

+3-7
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
1313
}
1414
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
1515
let mut _5: *const ();
16-
let mut _7: usize;
16+
let mut _6: usize;
1717
scope 5 (inlined std::ptr::metadata::<[u32]>) {
18-
let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
1918
}
2019
scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
2120
}
@@ -30,13 +29,10 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
3029
StorageDead(_3);
3130
StorageLive(_5);
3231
_5 = _4 as *const () (PtrToPtr);
33-
StorageLive(_7);
3432
StorageLive(_6);
35-
_6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
36-
_7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
33+
_6 = _1 as usize (PtrToMetadata);
34+
_0 = *const [u32] from (_5, _6);
3735
StorageDead(_6);
38-
_0 = *const [u32] from (_5, _7);
39-
StorageDead(_7);
4036
StorageDead(_5);
4137
StorageDead(_4);
4238
return;

‎tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir

+45-10
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,55 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
44
debug slice => _1;
55
debug index => _2;
66
let mut _0: &mut [u32];
7+
let mut _3: usize;
8+
let mut _4: usize;
79
scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) {
8-
let mut _3: *mut [u32];
9-
let mut _4: *mut [u32];
10+
let mut _5: *mut [u32];
11+
let mut _10: *mut [u32];
12+
scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) {
13+
let _6: usize;
14+
let mut _7: *mut u32;
15+
let mut _8: *mut u32;
16+
scope 3 {
17+
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
18+
}
19+
scope 7 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
20+
}
21+
scope 8 (inlined slice_from_raw_parts_mut::<u32>) {
22+
let mut _9: *mut ();
23+
scope 9 (inlined std::ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
24+
}
25+
scope 10 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
26+
}
27+
}
28+
}
29+
scope 4 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
30+
scope 5 (inlined std::ptr::metadata::<[u32]>) {
31+
}
32+
}
33+
}
1034
}
1135

1236
bb0: {
13-
StorageLive(_3);
14-
_3 = &raw mut (*_1);
15-
_4 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut(move _2, move _3) -> [return: bb1, unwind unreachable];
16-
}
17-
18-
bb1: {
19-
StorageDead(_3);
20-
_0 = &mut (*_4);
37+
_3 = move (_2.0: usize);
38+
_4 = move (_2.1: usize);
39+
StorageLive(_5);
40+
_5 = &raw mut (*_1);
41+
StorageLive(_6);
42+
_6 = SubUnchecked(_4, _3);
43+
StorageLive(_8);
44+
StorageLive(_7);
45+
_7 = _5 as *mut u32 (PtrToPtr);
46+
_8 = Offset(_7, _3);
47+
StorageDead(_7);
48+
StorageLive(_9);
49+
_9 = _8 as *mut () (PtrToPtr);
50+
_10 = *mut [u32] from (_9, _6);
51+
StorageDead(_9);
52+
StorageDead(_8);
53+
StorageDead(_6);
54+
StorageDead(_5);
55+
_0 = &mut (*_10);
2156
return;
2257
}
2358
}

‎tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir

+45-10
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,55 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
44
debug slice => _1;
55
debug index => _2;
66
let mut _0: &mut [u32];
7+
let mut _3: usize;
8+
let mut _4: usize;
79
scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) {
8-
let mut _3: *mut [u32];
9-
let mut _4: *mut [u32];
10+
let mut _5: *mut [u32];
11+
let mut _10: *mut [u32];
12+
scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) {
13+
let _6: usize;
14+
let mut _7: *mut u32;
15+
let mut _8: *mut u32;
16+
scope 3 {
17+
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
18+
}
19+
scope 7 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
20+
}
21+
scope 8 (inlined slice_from_raw_parts_mut::<u32>) {
22+
let mut _9: *mut ();
23+
scope 9 (inlined std::ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
24+
}
25+
scope 10 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
26+
}
27+
}
28+
}
29+
scope 4 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
30+
scope 5 (inlined std::ptr::metadata::<[u32]>) {
31+
}
32+
}
33+
}
1034
}
1135

1236
bb0: {
13-
StorageLive(_3);
14-
_3 = &raw mut (*_1);
15-
_4 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut(move _2, move _3) -> [return: bb1, unwind continue];
16-
}
17-
18-
bb1: {
19-
StorageDead(_3);
20-
_0 = &mut (*_4);
37+
_3 = move (_2.0: usize);
38+
_4 = move (_2.1: usize);
39+
StorageLive(_5);
40+
_5 = &raw mut (*_1);
41+
StorageLive(_6);
42+
_6 = SubUnchecked(_4, _3);
43+
StorageLive(_8);
44+
StorageLive(_7);
45+
_7 = _5 as *mut u32 (PtrToPtr);
46+
_8 = Offset(_7, _3);
47+
StorageDead(_7);
48+
StorageLive(_9);
49+
_9 = _8 as *mut () (PtrToPtr);
50+
_10 = *mut [u32] from (_9, _6);
51+
StorageDead(_9);
52+
StorageDead(_8);
53+
StorageDead(_6);
54+
StorageDead(_5);
55+
_0 = &mut (*_10);
2156
return;
2257
}
2358
}

0 commit comments

Comments
 (0)
Please sign in to comment.