diff options
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/intrinsics.rs | 28 | ||||
| -rw-r--r-- | library/core/src/ptr/metadata.rs | 32 |
2 files changed, 52 insertions, 8 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 9406efd7ab2..92f1bd27408 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2779,6 +2779,34 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { unreachable!() } +/// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`. +/// +/// This is used to implement functions like `slice::from_raw_parts_mut` and +/// `ptr::from_raw_parts` in a way compatible with the compiler being able to +/// change the possible layouts of pointers. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[cfg(not(bootstrap))] +pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P { + // To implement a fallback we'd have to assume the layout of the pointer, + // but the whole point of this intrinsic is that we shouldn't do that. + unreachable!() +} + +#[unstable(feature = "core_intrinsics", issue = "none")] +pub trait AggregateRawPtr<D> { + type Metadata: Copy; +} +impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*const T> for *const P { + type Metadata = <P as ptr::Pointee>::Metadata; +} +impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P { + type Metadata = <P as ptr::Pointee>::Metadata; +} + // Some functions are defined here because they accidentally got made // available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>. // (`transmute` also falls into this category, but it cannot be wrapped due to the diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 25a06f121cd..1226c8e2419 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -2,6 +2,8 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; +#[cfg(not(bootstrap))] +use crate::intrinsics::aggregate_raw_ptr; use crate::marker::Freeze; /// Provides the pointer metadata type of any pointed-to type. @@ -113,10 +115,17 @@ pub const fn from_raw_parts<T: ?Sized>( data_pointer: *const (), metadata: <T as Pointee>::Metadata, ) -> *const T { - // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T - // and PtrComponents<T> have the same memory layouts. Only std can make this - // guarantee. - unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr } + #[cfg(bootstrap)] + { + // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T + // and PtrComponents<T> have the same memory layouts. Only std can make this + // guarantee. + unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr } + } + #[cfg(not(bootstrap))] + { + aggregate_raw_ptr(data_pointer, metadata) + } } /// Performs the same functionality as [`from_raw_parts`], except that a @@ -130,10 +139,17 @@ pub const fn from_raw_parts_mut<T: ?Sized>( data_pointer: *mut (), metadata: <T as Pointee>::Metadata, ) -> *mut T { - // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T - // and PtrComponents<T> have the same memory layouts. Only std can make this - // guarantee. - unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr } + #[cfg(bootstrap)] + { + // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T + // and PtrComponents<T> have the same memory layouts. Only std can make this + // guarantee. + unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr } + } + #[cfg(not(bootstrap))] + { + aggregate_raw_ptr(data_pointer, metadata) + } } #[repr(C)] |
