about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-21 21:08:03 +0000
committerbors <bors@rust-lang.org>2024-04-21 21:08:03 +0000
commitfb898629a26e4acec59c928ce3ec00a62675d1cc (patch)
treeba73dfeeabaa003efb79a37a8cf7ae0de48e6cb5 /library
parent1b3fba066c21e7c3471fca710783fc1e6546a1ca (diff)
parent3315bf961d4d7dfafe3f8b01f892317e4f746861 (diff)
downloadrust-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.rs28
-rw-r--r--library/core/src/ptr/metadata.rs32
-rw-r--r--library/core/tests/ptr.rs8
-rw-r--r--library/core/tests/slice.rs13
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);
+}