Skip to content

Commit 9ffbc62

Browse files
committed
When replacing an old value we may not drop it in place
1 parent 8785f7b commit 9ffbc62

File tree

1 file changed

+8
-12
lines changed
  • library/std/src/sys/thread_local/native

1 file changed

+8
-12
lines changed

library/std/src/sys/thread_local/native/lazy.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,19 @@ where
7777

7878
let v = i.and_then(Option::take).unwrap_or_else(f);
7979

80+
// SAFETY: we cannot be inside a `LocalKey::with` scope, as the initializer
81+
// has already returned and the next scope only starts after we return
82+
// the pointer. Therefore, there can be no references to the old value,
83+
// even if it was initialized. Thus because we are !Sync we have exclusive
84+
// access to self.value and may replace it.
85+
let mut old_value = unsafe { self.value.get().replace(MaybeUninit::new(v)) };
8086
match self.state.replace(State::Alive) {
8187
State::Uninitialized => D::register_dtor(self),
82-
83-
State::Alive => {
84-
// An init occurred during a recursive call, this could be a panic in the future.
85-
86-
// SAFETY: we cannot be inside a `LocalKey::with` scope, as the initializer
87-
// has already returned and the next scope only starts after we return
88-
// the pointer. Therefore, there can be no references to the old value.
89-
unsafe { (*self.value.get()).assume_init_drop() }
90-
}
91-
88+
State::Alive => unsafe { old_value.assume_init_drop() },
9289
State::Destroyed(_) => unreachable!(),
9390
}
9491

95-
// SAFETY: we are !Sync so we have exclusive access to self.value.
96-
unsafe { (*self.value.get()).write(v) }
92+
self.value.get().cast()
9793
}
9894
}
9995

0 commit comments

Comments
 (0)