about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2023-03-28 11:39:09 +0200
committerjoboet <jonasboettiger@icloud.com>2023-03-30 14:49:43 +0200
commit97d49fcf60e0da214d8e08cb914821400d421caf (patch)
treeebd3afc7bb9c0c43645930f9b1b25813c8683047
parentc7f9739bada7c54b0d848cd029c4faa4665c9adc (diff)
downloadrust-97d49fcf60e0da214d8e08cb914821400d421caf.tar.gz
rust-97d49fcf60e0da214d8e08cb914821400d421caf.zip
core: use `pointer::write` to cleanup `LazyCell` initialization
-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