-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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 non-unsafe
.get_mut()
for Unsafecell
#76936
Add non-unsafe
.get_mut()
for Unsafecell
#76936
Conversation
7dca86f
to
09503fd
Compare
That seems like a different confusion, the comment after all explains that due to unique ownership there cannot be races. But yeah, the comment is confusing. |
Well, all standard library users. We don't know what other clients do outside the standard library. |
Thanks. :) @bors r+ rollup |
📌 Commit 853a9c4a4596892d6f69b9ec7f49177dfabbf1ef has been approved by |
ah wait looks like you wanted to squash some thing first |
Ok, I think we're getting there, @RalfJung 🙂 (thx for the review!). Now that we have an example of "using |
I don't really know where to post the following, so here it goes: Next steps / potential future PR(s)Also, as a possible follow-up for this PR, I was thinking about something such as unsafe {
// SAFETY: within this scope there are no other references to `x`'s contents,
// so ours is effectively unique.
let p1_exclusive: &mut i32 = &mut *p1.get();
*p1_exclusive += 27;
}
unsafe {
// SAFETY: within this scope nobody expects to have exclusive access to `x`'s contents,
// so we can have multiple shared accesses concurrently.
let p2_shared: &i32 = &*p2.get();
assert_eq!(*p2_shared, 42 + 27);
let p1_shared: &i32 = &*p1.get();
assert_eq!(*p1_shared, *p2_shared);
} to: unsafe {
// SAFETY: within this scope there are no other references to `x`'s contents,
// so ours is effectively unique.
let p1_exclusive: &mut i32 = p1.assume_unique()
*p1_exclusive += 27;
}
unsafe {
// SAFETY: within this scope nobody expects to have exclusive access to `x`'s contents,
// so we can have multiple shared accesses concurrently.
let p2_shared: &i32 = p2.assume_no_muts();
assert_eq!(*p2_shared, 42 + 27);
let p1_shared: &i32 = p1.assume_no_muts();
assert_eq!(*p1_shared, *p2_shared);
} This would have the benefit of lifetime-bounding the obtained references, which is not a bad thing either. Indeed, let's compare: //! Misusage
let x = UnsafeCell::new(42);
let p1 = &x;
let at_ft_mut = unsafe { &mut *p1.get() };
let p2 = &mut x;
let at_ft_mut_2 = p2.get_mut();
mem::swap(at_ft_mut, at_ft_mut_2); which compiles fine, to: //! Misusage
let x = UnsafeCell::new(42);
let p1 = &x;
let at_ft_mut = unsafe { p1.assume_unique() };
let p2 = &mut x;
let at_ft_mut_2 = p2.get_mut();
mem::swap(at_ft_mut, at_ft_mut_2); which fails with:
|
Honestly, that feels like a bit too much for a doc comment. That sounds more like a Nomicon chapter.^^
Yes, that sounds very useful. :) (for a separate PR though) |
Update the tracking issue number Updated the documentation for `UnsafeCell` Address review comments Address more review comments + minor changes
853a9c4
to
5886c38
Compare
Squashed 🙂 (I prefer not to force push while an interactive review is in process, since comments may get lost / track missing commits; now that that has been done, I can finally write the PR as two semantically meaningful commits: implement the method with the appropriate docs, and then simplify some |
That is much appreciated. :) It also makes it easier for me to see what changed from revision to revision. |
@bors r+ rollup |
📌 Commit 5886c38 has been approved by |
…mut, r=RalfJung Add non-`unsafe` `.get_mut()` for `Unsafecell` - Tracking issue: rust-lang#76943 As discussed in: https://internals.rust-lang.org/t/add-non-unsafe-get-mut-for-unsafecell/12407 - ### [Rendered documentation](https://modest-dubinsky-1f9f47.netlify.app/core/cell/struct.unsafecell) This PR tries to move the sound `&mut UnsafeCell<T> -> &mut T` projection that all the "downstream" constructions were already relying on, up to the root abstraction, where it rightfully belongs, and officially blessing it. - this **helps reduce the amount of `unsafe` snippets out there** (_c.f._, the second commit of this PR: rust-lang@09503fd) The fact that this getter is now expose for `UnsafeCell<T>` itself, will also help convey the idea that **`UnsafeCell` is not magical _w.r.t._ `&mut` accesses**, contrary to what some people incorrectly think. - Even the standard library itself at some point had such a confusion, _c.f._ this comment where there is a mention of multi-threaded (and thus _shared_) access despite dealing with exclusive references over unique ownership: https://github.com/rust-lang/rust/blob/59fb88d061544a035f3043b47594b34789204cee/library/core/src/cell.rs#L498-L499 r? @RalfJung
…mut, r=RalfJung Add non-`unsafe` `.get_mut()` for `Unsafecell` - Tracking issue: rust-lang#76943 As discussed in: https://internals.rust-lang.org/t/add-non-unsafe-get-mut-for-unsafecell/12407 - ### [Rendered documentation](https://modest-dubinsky-1f9f47.netlify.app/core/cell/struct.unsafecell) This PR tries to move the sound `&mut UnsafeCell<T> -> &mut T` projection that all the "downstream" constructions were already relying on, up to the root abstraction, where it rightfully belongs, and officially blessing it. - this **helps reduce the amount of `unsafe` snippets out there** (_c.f._, the second commit of this PR: rust-lang@09503fd) The fact that this getter is now expose for `UnsafeCell<T>` itself, will also help convey the idea that **`UnsafeCell` is not magical _w.r.t._ `&mut` accesses**, contrary to what some people incorrectly think. - Even the standard library itself at some point had such a confusion, _c.f._ this comment where there is a mention of multi-threaded (and thus _shared_) access despite dealing with exclusive references over unique ownership: https://github.com/rust-lang/rust/blob/59fb88d061544a035f3043b47594b34789204cee/library/core/src/cell.rs#L498-L499 r? @RalfJung
…mut, r=RalfJung Add non-`unsafe` `.get_mut()` for `Unsafecell` - Tracking issue: rust-lang#76943 As discussed in: https://internals.rust-lang.org/t/add-non-unsafe-get-mut-for-unsafecell/12407 - ### [Rendered documentation](https://modest-dubinsky-1f9f47.netlify.app/core/cell/struct.unsafecell) This PR tries to move the sound `&mut UnsafeCell<T> -> &mut T` projection that all the "downstream" constructions were already relying on, up to the root abstraction, where it rightfully belongs, and officially blessing it. - this **helps reduce the amount of `unsafe` snippets out there** (_c.f._, the second commit of this PR: rust-lang@09503fd) The fact that this getter is now expose for `UnsafeCell<T>` itself, will also help convey the idea that **`UnsafeCell` is not magical _w.r.t._ `&mut` accesses**, contrary to what some people incorrectly think. - Even the standard library itself at some point had such a confusion, _c.f._ this comment where there is a mention of multi-threaded (and thus _shared_) access despite dealing with exclusive references over unique ownership: https://github.com/rust-lang/rust/blob/59fb88d061544a035f3043b47594b34789204cee/library/core/src/cell.rs#L498-L499 r? @RalfJung
Rollup of 13 pull requests Successful merges: - rust-lang#76135 (Stabilize some Option methods as const) - rust-lang#76628 (Add sample defaults for config.toml ) - rust-lang#76846 (Avoiding unnecesary allocations at rustc_errors) - rust-lang#76867 (Use intra-doc links in core/src/iter when possible) - rust-lang#76868 (Finish moving to intra doc links for std::sync) - rust-lang#76872 (Remove DeclareMethods) - rust-lang#76936 (Add non-`unsafe` `.get_mut()` for `Unsafecell`) - rust-lang#76958 (Replace manual as_nanos and as_secs_f64 reimplementations) - rust-lang#76959 (Replace write_fmt with write!) - rust-lang#76961 (Add test for issue rust-lang#34634) - rust-lang#76962 (Use const_cstr macro in consts.rs) - rust-lang#76963 (Remove unused static_assert macro) - rust-lang#77000 (update Miri) Failed merges: r? `@ghost`
Is there a reason why fn get_mut(&mut self) -> &mut T {
&mut self.value
} |
Mostly an oversight 😅, I had been using an extension trait to implement this and thus tunnel-visioned on using the |
unsafe_cell_get_mut
#76943As discussed in: https://internals.rust-lang.org/t/add-non-unsafe-get-mut-for-unsafecell/12407
Rendered documentation
This PR tries to move the sound
&mut UnsafeCell<T> -> &mut T
projection that all the "downstream" constructions were already relying on, up to the root abstraction, where it rightfully belongs, and officially blessing it.unsafe
snippets out there (c.f., the second commit of this PR: 5886c38)The fact that this getter is now expose for
UnsafeCell<T>
itself, will also help convey the idea thatUnsafeCell
is not magical w.r.t.&mut
accesses, contrary to what some people incorrectly think.rust/library/core/src/cell.rs
Lines 498 to 499 in 59fb88d
r? @RalfJung