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

Box validity: update for new zero-sized rules #129748

Merged
merged 2 commits into from
Sep 3, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,19 @@
//!
//! # Memory layout
//!
//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
//! its allocation. It is valid to convert both ways between a [`Box`] and a
//! raw pointer allocated with the [`Global`] allocator, given that the
//! [`Layout`] used with the allocator is correct for the type. More precisely,
//! a `value: *mut T` that has been allocated with the [`Global`] allocator
//! with `Layout::for_value(&*value)` may be converted into a box using
//! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut
//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
//! [`Global`] allocator with [`Layout::for_value(&*value)`].
//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for its allocation. It is
//! valid to convert both ways between a [`Box`] and a raw pointer allocated with the [`Global`]
//! allocator, given that the [`Layout`] used with the allocator is correct for the type and the raw
//! pointer points to a valid value of the right type. More precisely, a `value: *mut T` that has
//! been allocated with the [`Global`] allocator with `Layout::for_value(&*value)` may be converted
//! into a box using [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut T`
//! obtained from [`Box::<T>::into_raw`] may be deallocated using the [`Global`] allocator with
//! [`Layout::for_value(&*value)`].
//!
//! For zero-sized values, the `Box` pointer still has to be [valid] for reads
//! and writes and sufficiently aligned. In particular, casting any aligned
//! non-zero integer literal to a raw pointer produces a valid pointer, but a
//! pointer pointing into previously allocated memory that since got freed is
//! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot
//! be used is to use [`ptr::NonNull::dangling`].
//! For zero-sized values, the `Box` pointer has to be non-null and sufficiently aligned. The
//! recommended way to build a Box to a ZST if `Box::new` cannot be used is to use
//! [`ptr::NonNull::dangling`]. Even for zero-sized types, the pointee type must be inhabited
//! to ensure that the Box points to a valid value of the given type.
Copy link
Member

Choose a reason for hiding this comment

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

Can we retain an example of what makes something "uninhabited" in this case, or a link to documentation that describes the notion of something being uninhabited?

Copy link
Member Author

Choose a reason for hiding this comment

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

I struggled a bit with what to say here and would welcome suggestions.

Copy link
Member

@saethlin saethlin Aug 31, 2024

Choose a reason for hiding this comment

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

A quick grep indicates this is the first time we're using the word in the standard library documentation. But the reference: https://github.com/rust-lang/reference/blob/master/src/glossary.md?plain=1#L284-L289 and the dev guide: https://github.com/rust-lang/rustc-dev-guide/blob/master/src/appendix/glossary.md?plain=1#L93 both provide a definition.

If we need to put a definition in the standard library docs I'm not sure where it would go, but I'd be happy pasting either of these in. Or just directing people to the reference, though that sounds bit-rotty unless we have something that checks that a link to that specific glossary entry still works.

Copy link
Member Author

Choose a reason for hiding this comment

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

Since I don't think (un)inhabited types should be special-cased here, I have chosen an entirely different wording now.

//!
//! 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
Expand Down
Loading