about summary refs log tree commit diff
path: root/src/libcore/alloc
diff options
context:
space:
mode:
authorCAD97 <cad97@cad97.com>2020-07-18 18:06:52 -0400
committerCAD97 <cad97@cad97.com>2020-07-18 18:27:39 -0400
commit1821e3d75ca7a0165a0919d32b2244751ef8b2e4 (patch)
tree5432e1cab99d5ca0ad3ceadbe8cbfb8ca69bb67a /src/libcore/alloc
parent1fa54ad9680cc82e7301f8ed4e9b7402dfd6ce0e (diff)
downloadrust-1821e3d75ca7a0165a0919d32b2244751ef8b2e4.tar.gz
rust-1821e3d75ca7a0165a0919d32b2244751ef8b2e4.zip
re-add Layout::for_value_raw
This was accidentally removed in rust-lang/rust#70362
56cbf2f22aeb6448acd7eb49e9b2554c80bdbf79
Diffstat (limited to 'src/libcore/alloc')
-rw-r--r--src/libcore/alloc/layout.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs
index ae7ae704465..7129f0f2402 100644
--- a/src/libcore/alloc/layout.rs
+++ b/src/libcore/alloc/layout.rs
@@ -131,7 +131,42 @@ impl Layout {
     pub fn for_value<T: ?Sized>(t: &T) -> Self {
         let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
         debug_assert!(Layout::from_size_align(size, align).is_ok());
-        // SAFETY: see rationale in `new` for why this is using an unsafe variant below
+        // SAFETY: see rationale in `new` for why this is using the unsafe variant
+        unsafe { Layout::from_size_align_unchecked(size, align) }
+    }
+
+    /// Produces layout describing a record that could be used to
+    /// allocate backing structure for `T` (which could be a trait
+    /// or other unsized type like a slice).
+    ///
+    /// # Safety
+    ///
+    /// This function is only safe to call if the following conditions hold:
+    ///
+    /// - If `T` is `Sized`, this function is always safe to call.
+    /// - If the unsized tail of `T` is:
+    ///     - a [slice], then the length of the slice tail must be an intialized
+    ///       integer, and the size of the *entire value*
+    ///       (dynamic tail length + statically sized prefix) must fit in `isize`.
+    ///     - a [trait object], then the vtable part of the pointer must point
+    ///       to a valid vtable for the type `T` acquired by an unsizing coersion,
+    ///       and the size of the *entire value*
+    ///       (dynamic tail length + statically sized prefix) must fit in `isize`.
+    ///     - an (unstable) [extern type], then this function is always safe to
+    ///       call, but may panic or otherwise return the wrong value, as the
+    ///       extern type's layout is not known. This is the same behavior as
+    ///       [`Layout::for_value`] on a reference to an extern type tail.
+    ///     - otherwise, it is conservatively not allowed to call this function.
+    ///
+    /// [slice]: ../../std/primitive.slice.html
+    /// [trait object]: ../../book/ch17-02-trait-objects.html
+    /// [extern type]: ../../unstable-book/language-features/extern-types.html
+    #[unstable(feature = "layout_for_ptr", issue = "69835")]
+    pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
+        // SAFETY: we pass along the prerequisites of these functions to the caller
+        let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) };
+        debug_assert!(Layout::from_size_align(size, align).is_ok());
+        // SAFETY: see rationale in `new` for why this is using the unsafe variant
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }