about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-07 17:27:35 +0100
committerGitHub <noreply@github.com>2020-03-07 17:27:35 +0100
commit963b0aa541a68d9ffceb6685f785f9ae485964f7 (patch)
tree24774445fb5edb19f438d78aef8f60f5814aae11
parentf1f4864de3ecfa106d03f2172f2c80edf8eeb02c (diff)
parent09d3ba13afb8fdf449928b160431787e2d259db1 (diff)
downloadrust-963b0aa541a68d9ffceb6685f785f9ae485964f7.tar.gz
rust-963b0aa541a68d9ffceb6685f785f9ae485964f7.zip
Rollup merge of #69794 - TimDiekmann:dangling, r=Amanieu
Add `Layout::dangling()` to return a well-aligned `NonNull<u8>`

Adds a convenient function to `Layout` to create a `NonNull<u8>` out of a layout to be returned on ZST allocations.

This is the first item on the roadmap to support ZSTs in `AllocRef`: https://github.com/rust-lang/wg-allocators/issues/38#issuecomment-595861542

r? @Amanieu
-rw-r--r--src/libcore/alloc.rs12
-rw-r--r--src/libcore/tests/alloc.rs3
-rw-r--r--src/libcore/tests/lib.rs1
3 files changed, 16 insertions, 0 deletions
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index f3a2b73f2b8..0a7a8ab266a 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -140,6 +140,18 @@ impl Layout {
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }
 
+    /// Creates a `NonNull` that is dangling, but well-aligned for this Layout.
+    ///
+    /// Note that the pointer value may potentially represent a valid pointer,
+    /// which means this must not be used as a "not yet initialized"
+    /// sentinel value. Types that lazily allocate must track initialization by
+    /// some other means.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    pub const fn dangling(&self) -> NonNull<u8> {
+        // align is non-zero and a power of two
+        unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
+    }
+
     /// Creates a layout describing the record that can hold a value
     /// of the same layout as `self`, but that also is aligned to
     /// alignment `align` (measured in bytes).
diff --git a/src/libcore/tests/alloc.rs b/src/libcore/tests/alloc.rs
index 63537ba23d8..c8592e40a69 100644
--- a/src/libcore/tests/alloc.rs
+++ b/src/libcore/tests/alloc.rs
@@ -1,10 +1,13 @@
 use core::alloc::Layout;
+use core::ptr::NonNull;
 
 #[test]
 fn const_unchecked_layout() {
     const SIZE: usize = 0x2000;
     const ALIGN: usize = 0x1000;
     const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) };
+    const DANGLING: NonNull<u8> = LAYOUT.dangling();
     assert_eq!(LAYOUT.size(), SIZE);
     assert_eq!(LAYOUT.align(), ALIGN);
+    assert_eq!(Some(DANGLING), NonNull::new(ALIGN as *mut u8));
 }
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 991458db5b7..71a061af289 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -1,3 +1,4 @@
+#![feature(alloc_layout_extra)]
 #![feature(bool_to_option)]
 #![feature(bound_cloned)]
 #![feature(box_syntax)]