Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: No (opsem) Magic Boxes #3712

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
9 changes: 6 additions & 3 deletions text/3712-box-yesalias.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ The following are not valid values of type `WellFormed<T>`, and a typed copy tha
* A pointer with an address that is not well-aligned for `T` (or in the case of a DST, the `align_of_val_raw` of the value), or
* A pointer with an address that offsetting that address (as though by `.wrapping_byte_offset`) by `size_of_val_raw` bytes would wrap arround the address space

The [`alloc::boxed::Box<T>`] type shall be laid out as though a `repr(transparent)` struct containing a field of type `WellFormed<T>`. The behaviour of doing a typed copy as type [`alloc::boxed::Box<T>`] shall be the same as though a typed copy of the struct `#[repr(transparent)] struct Box<T>(WellFormed<T>);`.
The [`alloc::boxed::Box<T>`] type shall be laid out as though a `repr(transparent)` struct containing a field of type `WellFormed<T>`. The behaviour of doing a typed copy as type [`alloc::boxed::Box<T>`] shall be the same as though a typed copy of the struct `#[repr(transparent)] struct Box<T>(WellFormed<T>);`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks to be a new guarantee? We currently don't normatively say anything about the layout of Box, AFAIK.

Also see this; Cc @CAD97

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stdlib docs promise it has the same layout and abi as a pointer, and also promises niche optimization.

https://doc.rust-lang.org/alloc/boxed/index.html#memory-layout

So long as T: Sized, a Box<T> is guaranteed to be represented as a single pointer and is also ABI-compatible with C pointers (i.e. the C type T*).

https://doc.rust-lang.org/core/primitive.fn.html#abi-compatibility

*const T, *mut T, &T, &mut T, Box<T> (specifically, only Box<T, Global>), and NonNull<T> are all ABI-compatible with each other for all T. They are also ABI-compatible with each other for different T if they have the same metadata type (<T as Pointee>::Metadata).

(The last sentence implies the abi, and thus layout, holds for T: !Sized pointers as well)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay :)


[`alloc::boxed::Box<T>`] shall have a niche of the all zeroes bit pattern, which is used for the `None` value of [`core::option::Option<Box<T>>`] (and similar types). Additional invalid values may be used as niches, but no guarantees are made about those niches.

When the unstable feature [`allocator_api`] is in use, the type [`alloc::boxed::Box<T,A>`] (where `A` is not the type `Global`, `alloc::boxed::Box<T,Global>` is the same type as [`alloc::boxed::Box<T>`]) is laid out as a struct containing a field of type `WellFormed<T>`, and a field of type `A`, and a typed copy as [`alloc::boxed::Box<T,A>`] is the same as a typed copy of that struct. The order and offsets of these fields is not specified, even for an `A` of size 0 and alignment 1.
When the unstable feature [`allocator_api`] is in use (or after its stabilization), the type [`alloc::boxed::Box<T,A>`] (where `A` is not the type `Global`, `alloc::boxed::Box<T,Global>` is the same type as [`alloc::boxed::Box<T>`]) is laid out as a struct containing a field of type `WellFormed<T>`, and a field of type `A`, and a typed copy as [`alloc::boxed::Box<T,A>`] is the same as a typed copy of that struct. The order and offsets of these fields is not specified, even for an `A` of size 0 and alignment 1.

A value of type [`alloc::boxed::Box<T,A>`] is invalid if either field is invalid.

In addition to the above, [RFC 3336] is amended to remove the `MaybeDangling` behaviour of `ManuallyDrop` as it is no longer necessary. The type itself is preserved as it can be useful in other contexts.
chorman0773 marked this conversation as resolved.
Show resolved Hide resolved

# Drawbacks
[drawbacks]: #drawbacks

Expand Down Expand Up @@ -121,4 +123,5 @@ Finally, should optimizations begin to be implemented in Rust compilers that cou
[`alloc::boxed::Box<T,A>`]: https://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html
[`core::option::Option<T>`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html
[`core::ptr::NonNull<T>`]: https://doc.rust-lang.org/nightly/core/ptr/struct.NonNull.html
[RFC 3204]: https://github.com/rust-lang/rfcs/pull/3204
[RFC 3204]: https://github.com/rust-lang/rfcs/pull/3204
[RFC 3336]: https://github.com/rust-lang/rfcs/blob/master/text/3336-maybe-dangling.md