about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/cell/lazy.rs15
1 files changed, 7 insertions, 8 deletions
diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 4039cc26812..aff3388529a 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -115,16 +115,15 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
         // SAFETY:
         // If the closure accessed the cell through something like a reentrant
         // mutex, but caught the panic resulting from the state being poisoned,
-        // the mutable borrow for `state` will be invalidated, so create a new
-        // one here.
-        let state = unsafe { &mut *this.state.get() };
-        *state = State::Init(data);
+        // the mutable borrow for `state` will be invalidated, so we need to
+        // go through the `UnsafeCell` pointer here. The state can only be
+        // poisoned at this point, so using `write` to skip the destructor
+        // of `State` should help the optimizer.
+        unsafe { this.state.get().write(State::Init(data)) };
 
         // SAFETY:
-        // A reference obtained by downcasting from the mutable borrow would
-        // become stale the next time `force` is called (since there is a conflict
-        // between the mutable reference here and the shared reference there).
-        // Do a new shared borrow of the state instead.
+        // The previous references were invalidated by the `write` call above,
+        // so do a new shared borrow of the state instead.
         let state = unsafe { &*this.state.get() };
         let State::Init(data) = state else { unreachable!() };
         data