Rollup merge of #124251 - scottmcm:unop-ptr-metadata, r=oli-obk · model-checking/verify-rust-std@565dce2 (original) (raw)

4 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -2821,6 +2821,21 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
2821 2821 type Metadata = <P as ptr::Pointee>::Metadata;
2822 2822 }
2823 2823
2824 +/// Lowers in MIR to `Rvalue::UnaryOp` with `UnOp::PtrMetadata`.
2825 +///
2826 +/// This is used to implement functions like `ptr::metadata`.
2827 +#[rustc_nounwind]
2828 +#[unstable(feature = "core_intrinsics", issue = "none")]
2829 +#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
2830 +#[rustc_intrinsic]
2831 +#[rustc_intrinsic_must_be_overridden]
2832 +#[cfg(not(bootstrap))]
2833 +pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *const P) -> M {
2834 +// To implement a fallback we'd have to assume the layout of the pointer,
2835 +// but the whole point of this intrinsic is that we shouldn't do that.
2836 +unreachable!()
2837 +}
2838 +
2824 2839 // Some functions are defined here because they accidentally got made
2825 2840 // available in this module on stable. See https://github.com/rust-lang/rust/issues/15702.
2826 2841 // (`transmute` also falls into this category, but it cannot be wrapped due to the
Original file line number Diff line number Diff line change
@@ -360,6 +360,10 @@ define!("mir_assume", fn Assume(operand: bool));
360 360 define!("mir_deinit", fn Deinit<T>(place: T));
361 361 define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
362 362 define!("mir_len", fn Len<T>(place: T) -> usize);
363 +define!(
364 +"mir_ptr_metadata",
365 +fn PtrMetadata<P: ?Sized>(place: *const P) -> <P as ::core::ptr::Pointee>::Metadata
366 +);
363 367 define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T);
364 368 define!("mir_retag", fn Retag<T>(place: T));
365 369 define!("mir_move", fn Move<T>(place: T) -> T);
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@
3 3 use crate::fmt;
4 4 use crate::hash::{Hash, Hasher};
5 5 use crate::intrinsics::aggregate_raw_ptr;
6 +#[cfg(not(bootstrap))]
7 +use crate::intrinsics::ptr_metadata;
6 8 use crate:📑:Freeze;
7 9
8 10 /// Provides the pointer metadata type of any pointed-to type.
@@ -94,10 +96,17 @@ pub trait Thin = Pointee<Metadata = ()>;
94 96 #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
95 97 #[inline]
96 98 pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
97 -// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
98 -// and PtrComponents have the same memory layouts. Only std can make this
99 -// guarantee.
100 -unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
99 +#[cfg(bootstrap)]
100 +{
101 +// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
102 +// and PtrComponents have the same memory layouts. Only std can make this
103 +// guarantee.
104 +unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
105 +}
106 +#[cfg(not(bootstrap))]
107 +{
108 +ptr_metadata(ptr)
109 +}
101 110 }
102 111
103 112 /// Forms a (possibly-wide) raw pointer from a data pointer and metadata.
@@ -132,22 +141,26 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
132 141 }
133 142
134 143 #[repr(C)]
144 +#[cfg(bootstrap)]
135 145 union PtrRepr<T: ?Sized> {
136 146 const_ptr: *const T,
137 147 mut_ptr: *mut T,
138 148 components: PtrComponents<T>,
139 149 }
140 150
141 151 #[repr(C)]
152 +#[cfg(bootstrap)]
142 153 struct PtrComponents<T: ?Sized> {
143 154 data_pointer: *const (),
144 155 metadata: <T as Pointee>::Metadata,
145 156 }
146 157
147 158 // Manual impl needed to avoid `T: Copy` bound.
159 +#[cfg(bootstrap)]
148 160 impl<T: ?Sized> Copy for PtrComponents<T> {}
149 161
150 162 // Manual impl needed to avoid `T: Clone` bound.
163 +#[cfg(bootstrap)]
151 164 impl<T: ?Sized> Clone for PtrComponents<T> {
152 165 fn clone(&self) -> Self {
153 166 *self
Original file line number Diff line number Diff line change
@@ -1171,3 +1171,15 @@ fn test_ptr_from_raw_parts_in_const() {
1171 1171 assert_eq!(EMPTY_SLICE_PTR.addr(), 123);
1172 1172 assert_eq!(EMPTY_SLICE_PTR.len(), 456);
1173 1173 }
1174 +
1175 +#[test]
1176 +fn test_ptr_metadata_in_const() {
1177 +use std::fmt::Debug;
1178 +
1179 +const ARRAY_META: () = std::ptr::metadata::<[u16; 3]>(&[1, 2, 3]);
1180 +const SLICE_META: usize = std::ptr::metadata::<[u16]>(&[1, 2, 3]);
1181 +const DYN_META: DynMetadata<dyn Debug> = std::ptr::metadata::<dyn Debug>(&[0_u8; 42]);
1182 +assert_eq!(ARRAY_META, ());
1183 +assert_eq!(SLICE_META, 3);
1184 +assert_eq!(DYN_META.size_of(), 42);
1185 +}