Skip to content

Document return value of zero-size/zero-heap pointer types. #39757

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ impl<T> Arc<T> {
/// To avoid a memory leak the pointer must be converted back to an `Arc` using
/// [`Arc::from_raw`][from_raw].
///
/// If `T` is zero-sized (e.g. `Arc<()>`), the returned pointer address
/// will be meaningless.
Copy link
Member Author

Choose a reason for hiding this comment

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

Nit for myself: I can probably just s/will be meaningless/is meaningless/.

Copy link
Member

Choose a reason for hiding this comment

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

I think for Rc and Arc this is wrong, because from_raw exists and there's the two refcounts, not just the ZST.

Copy link
Contributor

Choose a reason for hiding this comment

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

@eddyb can you elaborate on what you mean here? This method returns a pointer to the contents, right?

But it does seem weird to simultaneously say that the return value is meaningless, and then have from_raw say that the result must have been generated by into_raw.

I guess I'm not sure what meaningless means, really.

Copy link
Member

Choose a reason for hiding this comment

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

The value is one-byte-past-the-refcounts and can be used to get back an Rc, and you can distinguish between them, so definitely not meaningless (whereas an &ZST by itself is useless for anything short of a proof that there is a value of type ZST somewhere).

///
/// [from_raw]: struct.Arc.html#method.from_raw
///
/// # Examples
Expand Down
3 changes: 3 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ impl<T: ?Sized> Box<T> {
/// proper way to do so is to convert the raw pointer back into a
/// `Box` with the [`Box::from_raw`] function.
///
/// If `T` is zero-sized (e.g. `Box<()>`), the returned pointer address
/// will be meaningless.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
/// is so that there is no conflict with a method on the inner type.
Expand Down
3 changes: 3 additions & 0 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ impl<T> Rc<T> {
/// To avoid a memory leak the pointer must be converted back to an `Rc` using
/// [`Rc::from_raw`][from_raw].
///
/// If `T` is zero-sized (e.g. `Rc<()>`), the returned pointer address
/// will be meaningless.
///
/// [from_raw]: struct.Rc.html#method.from_raw
///
/// # Examples
Expand Down
6 changes: 6 additions & 0 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,9 @@ impl<T> [T] {
/// The caller must ensure that the slice outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
///
/// If the slice is empty, the returned pointer address will be
/// meaningless.
///
/// Modifying the slice may cause its buffer to be reallocated, which
/// would also make any pointers to it invalid.
///
Expand All @@ -463,6 +466,9 @@ impl<T> [T] {
/// The caller must ensure that the slice outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
///
/// If the slice is empty, the returned pointer address will be
/// meaningless.
///
/// Modifying the slice may cause its buffer to be reallocated, which
/// would also make any pointers to it invalid.
///
Expand Down
3 changes: 3 additions & 0 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ impl str {
/// [`u8`]. This pointer will be pointing to the first byte of the string
/// slice.
///
/// If the string slice is empty, the returned pointer address will be
/// meaningless.
///
/// [`u8`]: primitive.u8.html
///
/// # Examples
Expand Down
9 changes: 9 additions & 0 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ impl<T:Copy> Cell<T> {

/// Returns a raw pointer to the underlying data in this cell.
///
/// If `T` is zero-sized (e.g. `Cell<()>`), the returned pointer address
/// will be meaningless.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -771,6 +774,9 @@ impl<T: ?Sized> RefCell<T> {

/// Returns a raw pointer to the underlying data in this cell.
///
/// If `T` is zero-sized (e.g. `RefCell<()>`), the returned pointer address
/// will be meaningless.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -1188,6 +1194,9 @@ impl<T: ?Sized> UnsafeCell<T> {
/// `&mut T`, and ensure that there are no mutations or mutable
/// aliases going on when casting to `&T`
///
/// If `T` is zero-sized (e.g. `UnsafeCell<()>`), the returned pointer
/// address will be meaningless.
///
/// # Examples
///
/// ```
Expand Down