diff options
| author | bors <bors@rust-lang.org> | 2020-03-22 18:37:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-03-22 18:37:19 +0000 |
| commit | d1e81ef234ff5c2e0e3a69cb4e8e5f5b0fe1fd83 (patch) | |
| tree | ca5c3aa589727e4c1845fa6865015841f1d62db9 /src/libcore/alloc.rs | |
| parent | 1902d1e0de179498d0cb7fd4856d1e0ffcd52095 (diff) | |
| parent | dd973d1b1235813c5e38a092272f2231800b1e53 (diff) | |
| download | rust-d1e81ef234ff5c2e0e3a69cb4e8e5f5b0fe1fd83.tar.gz rust-d1e81ef234ff5c2e0e3a69cb4e8e5f5b0fe1fd83.zip | |
Auto merge of #69079 - CAD97:layout-of-ptr, r=RalfJung
Allow calculating the layout behind a pointer There was some discussion around allowing this previously. This does make the requirement for raw pointers to have valid metadata exposed as part of the std API (as a safety invariant, not validity invariant), though I think this is not strictly necessarily required as of current. cc @rust-lang/wg-unsafe-code-guidelines Naming is hard; I picked the best "obvious" name I could come up with. If it's agreed that this is actually a desired API surface, I'll file a tracking issue and update the attributes.
Diffstat (limited to 'src/libcore/alloc.rs')
| -rw-r--r-- | src/libcore/alloc.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index d2a513451cc..be20a1cde36 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -140,6 +140,42 @@ impl Layout { 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 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 + #[inline] + #[cfg(not(bootstrap))] + #[unstable(feature = "layout_for_ptr", issue = "69835")] + pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self { + let (size, align) = (mem::size_of_val_raw(t), mem::align_of_val_raw(t)); + // See rationale in `new` for why this is using an unsafe variant below + debug_assert!(Layout::from_size_align(size, align).is_ok()); + 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, |
