diff options
| author | bors <bors@rust-lang.org> | 2024-04-21 21:08:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-21 21:08:03 +0000 |
| commit | fb898629a26e4acec59c928ce3ec00a62675d1cc (patch) | |
| tree | ba73dfeeabaa003efb79a37a8cf7ae0de48e6cb5 /library | |
| parent | 1b3fba066c21e7c3471fca710783fc1e6546a1ca (diff) | |
| parent | 3315bf961d4d7dfafe3f8b01f892317e4f746861 (diff) | |
| download | rust-fb898629a26e4acec59c928ce3ec00a62675d1cc.tar.gz rust-fb898629a26e4acec59c928ce3ec00a62675d1cc.zip | |
Auto merge of #124241 - matthiaskrgr:rollup-xhu90xr, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #123840 (Add an intrinsic for `ptr::from_raw_parts(_mut)`) - #124224 (cleanup: unnecessary clone during lower generics args) - #124229 (Add gnullvm targets to manifest) - #124231 (remove from reviewers) - #124235 (Move some tests) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'library')
| -rw-r--r-- | library/core/src/intrinsics.rs | 28 | ||||
| -rw-r--r-- | library/core/src/ptr/metadata.rs | 32 | ||||
| -rw-r--r-- | library/core/tests/ptr.rs | 8 | ||||
| -rw-r--r-- | library/core/tests/slice.rs | 13 |
4 files changed, 73 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)] diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 2c82eda9a58..7b55c2bf8a8 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -1163,3 +1163,11 @@ fn test_null_array_as_slice() { assert!(ptr.is_null()); assert_eq!(ptr.len(), 4); } + +#[test] +fn test_ptr_from_raw_parts_in_const() { + const EMPTY_SLICE_PTR: *const [i32] = + std::ptr::slice_from_raw_parts(std::ptr::without_provenance(123), 456); + assert_eq!(EMPTY_SLICE_PTR.addr(), 123); + assert_eq!(EMPTY_SLICE_PTR.len(), 456); +} diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index c5743eda3e8..ffe8ffcc7f2 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -2678,3 +2678,16 @@ fn test_get_many_mut_duplicate() { let mut v = vec![1, 2, 3, 4, 5]; assert!(v.get_many_mut([1, 3, 3, 4]).is_err()); } + +#[test] +fn test_slice_from_raw_parts_in_const() { + static FANCY: i32 = 4; + static FANCY_SLICE: &[i32] = unsafe { std::slice::from_raw_parts(&FANCY, 1) }; + assert_eq!(FANCY_SLICE.as_ptr(), std::ptr::addr_of!(FANCY)); + assert_eq!(FANCY_SLICE.len(), 1); + + const EMPTY_SLICE: &[i32] = + unsafe { std::slice::from_raw_parts(std::ptr::without_provenance(123456), 0) }; + assert_eq!(EMPTY_SLICE.as_ptr().addr(), 123456); + assert_eq!(EMPTY_SLICE.len(), 0); +} |
