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

Add comment about UnsafeCell in MaybeUninit #66051

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion src/libcore/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ impl<T> MaybeUninit<T> {
/// Gets a pointer to the contained value. Reading from this pointer or turning it
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
/// Writing to memory that this pointer (non-transitively) points to is undefined behavior
/// (except inside an `UnsafeCell<T>`).
/// (except inside an `UnsafeCell<T>` when already initialized).
Copy link
Member

Choose a reason for hiding this comment

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

I don't really understand the goal of this change. It is also not correct; the interior mutability exception is entirely orthogonal to initialization.

Could you elaborate a bit more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, maybe this change isn't helping to make things more clear...
This is roughly what I was doing:

let value: MaybeUninit<UnsafeCell<bool>> = MaybeUninit::uninit();
let slot = (&*value.as_ptr()).get() as *mut T;
slot.write(true);

But because UnsafeCell::get takes a reference, this would be invalid, right? There would temporary be a reference to an uninitialized UnsafeCell<bool>.

So I would think the exception that you can write through MaybeUninit::as_ptr when it wraps an UnsafeCell would only be correct if it was already initialized.

Copy link
Member

Choose a reason for hiding this comment

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

So I would think the exception that you can write through MaybeUninit::as_ptr when it wraps an UnsafeCell would only be correct if it was already initialized.

No, the exception always applies. It's just you cannot make use of it through UnsafeCell::get. When writing unsafe code, you have to get all clauses of all constructs you use satisfied. Your example is fine as far as MaybeUninit::as_ptr is concerned -- it it what you are doing later that breaks it. Under some proposed memory model, if you use transmute to turn *const UnsafeCell<bool> into *mut bool, that is allowed and then you may use ptr:.write to initialize the bool.

///
/// # Examples
///
Expand Down