@@ -496,10 +496,7 @@ impl<T: ?Sized> Cell<T> {
496496 #[ inline]
497497 #[ stable( feature = "cell_get_mut" , since = "1.11.0" ) ]
498498 pub fn get_mut ( & mut self ) -> & mut T {
499- // SAFETY: This can cause data races if called from a separate thread,
500- // but `Cell` is `!Sync` so this won't happen, and `&mut` guarantees
501- // unique access.
502- unsafe { & mut * self . value . get ( ) }
499+ self . value . get_mut ( )
503500 }
504501
505502 /// Returns a `&Cell<T>` from a `&mut T`
@@ -945,8 +942,7 @@ impl<T: ?Sized> RefCell<T> {
945942 #[ inline]
946943 #[ stable( feature = "cell_get_mut" , since = "1.11.0" ) ]
947944 pub fn get_mut ( & mut self ) -> & mut T {
948- // SAFETY: `&mut` guarantees unique access.
949- unsafe { & mut * self . value . get ( ) }
945+ self . value . get_mut ( )
950946 }
951947
952948 /// Undo the effect of leaked guards on the borrow state of the `RefCell`.
@@ -1543,8 +1539,11 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
15431539/// allow internal mutability, such as `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their
15441540/// internal data. There is *no* legal way to obtain aliasing `&mut`, not even with `UnsafeCell<T>`.
15451541///
1546- /// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to
1547- /// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly.
1542+ /// The `UnsafeCell` API itself is technically very simple: [`.get()`] gives you a raw pointer
1543+ /// `*mut T` to its contents. It is up to _you_ as the abstraction designer to use that raw pointer
1544+ /// correctly.
1545+ ///
1546+ /// [`.get()`]: `UnsafeCell::get`
15481547///
15491548/// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious:
15501549///
@@ -1571,21 +1570,70 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
15711570/// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T`
15721571/// co-exist with it. A `&mut T` must always be unique.
15731572///
1574- /// Note that while mutating or mutably aliasing the contents of an `&UnsafeCell<T>` is
1575- /// ok (provided you enforce the invariants some other way), it is still undefined behavior
1576- /// to have multiple `&mut UnsafeCell<T>` aliases.
1573+ /// Note that whilst mutating the contents of an `&UnsafeCell<T>` (even while other
1574+ /// `&UnsafeCell<T>` references alias the cell) is
1575+ /// ok (provided you enforce the above invariants some other way), it is still undefined behavior
1576+ /// to have multiple `&mut UnsafeCell<T>` aliases. That is, `UnsafeCell` is a wrapper
1577+ /// designed to have a special interaction with _shared_ accesses (_i.e._, through an
1578+ /// `&UnsafeCell<_>` reference); there is no magic whatsoever when dealing with _exclusive_
1579+ /// accesses (_e.g._, through an `&mut UnsafeCell<_>`): neither the cell nor the wrapped value
1580+ /// may be aliased for the duration of that `&mut` borrow.
1581+ /// This is showcased by the [`.get_mut()`] accessor, which is a non-`unsafe` getter that yields
1582+ /// a `&mut T`.
1583+ ///
1584+ /// [`.get_mut()`]: `UnsafeCell::get_mut`
15771585///
15781586/// # Examples
15791587///
1588+ /// Here is an example showcasing how to soundly mutate the contents of an `UnsafeCell<_>` despite
1589+ /// there being multiple references aliasing the cell:
1590+ ///
15801591/// ```
15811592/// use std::cell::UnsafeCell;
15821593///
1583- /// # #[allow(dead_code)]
1584- /// struct NotThreadSafe<T> {
1585- /// value: UnsafeCell<T>,
1594+ /// let x: UnsafeCell<i32> = 42.into();
1595+ /// // Get multiple / concurrent / shared references to the same `x`.
1596+ /// let (p1, p2): (&UnsafeCell<i32>, &UnsafeCell<i32>) = (&x, &x);
1597+ ///
1598+ /// unsafe {
1599+ /// // SAFETY: within this scope there are no other references to `x`'s contents,
1600+ /// // so ours is effectively unique.
1601+ /// let p1_exclusive: &mut i32 = &mut *p1.get(); // -- borrow --+
1602+ /// *p1_exclusive += 27; // |
1603+ /// } // <---------- cannot go beyond this point -------------------+
1604+ ///
1605+ /// unsafe {
1606+ /// // SAFETY: within this scope nobody expects to have exclusive access to `x`'s contents,
1607+ /// // so we can have multiple shared accesses concurrently.
1608+ /// let p2_shared: &i32 = &*p2.get();
1609+ /// assert_eq!(*p2_shared, 42 + 27);
1610+ /// let p1_shared: &i32 = &*p1.get();
1611+ /// assert_eq!(*p1_shared, *p2_shared);
15861612/// }
1613+ /// ```
15871614///
1588- /// unsafe impl<T> Sync for NotThreadSafe<T> {}
1615+ /// The following example showcases the fact that exclusive access to an `UnsafeCell<T>`
1616+ /// implies exclusive access to its `T`:
1617+ ///
1618+ /// ```rust
1619+ /// #![feature(unsafe_cell_get_mut)]
1620+ /// #![forbid(unsafe_code)] // with exclusive accesses,
1621+ /// // `UnsafeCell` is a transparent no-op wrapper,
1622+ /// // so no need for `unsafe` here.
1623+ /// use std::cell::UnsafeCell;
1624+ ///
1625+ /// let mut x: UnsafeCell<i32> = 42.into();
1626+ ///
1627+ /// // Get a compile-time-checked unique reference to `x`.
1628+ /// let p_unique: &mut UnsafeCell<i32> = &mut x;
1629+ /// // With an exclusive reference, we can mutate the contents for free.
1630+ /// *p_unique.get_mut() = 0;
1631+ /// // Or, equivalently:
1632+ /// x = UnsafeCell::new(0);
1633+ ///
1634+ /// // When we own the value, we can extract the contents for free.
1635+ /// let contents: i32 = x.into_inner();
1636+ /// assert_eq!(contents, 0);
15891637/// ```
15901638#[ lang = "unsafe_cell" ]
15911639#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1663,6 +1711,29 @@ impl<T: ?Sized> UnsafeCell<T> {
16631711 self as * const UnsafeCell < T > as * const T as * mut T
16641712 }
16651713
1714+ /// Returns a mutable reference to the underlying data.
1715+ ///
1716+ /// This call borrows the `UnsafeCell` mutably (at compile-time) which
1717+ /// guarantees that we possess the only reference.
1718+ ///
1719+ /// # Examples
1720+ ///
1721+ /// ```
1722+ /// #![feature(unsafe_cell_get_mut)]
1723+ /// use std::cell::UnsafeCell;
1724+ ///
1725+ /// let mut c = UnsafeCell::new(5);
1726+ /// *c.get_mut() += 1;
1727+ ///
1728+ /// assert_eq!(*c.get_mut(), 6);
1729+ /// ```
1730+ #[ inline]
1731+ #[ unstable( feature = "unsafe_cell_get_mut" , issue = "76943" ) ]
1732+ pub fn get_mut ( & mut self ) -> & mut T {
1733+ // SAFETY: (outer) `&mut` guarantees unique access.
1734+ unsafe { & mut * self . get ( ) }
1735+ }
1736+
16661737 /// Gets a mutable pointer to the wrapped value.
16671738 /// The difference to [`get`] is that this function accepts a raw pointer,
16681739 /// which is useful to avoid the creation of temporary references.
0 commit comments