Skip to content

Commit 23e49dd

Browse files
committed
Auto merge of #76370 - fusion-engineering-forks:synconcecell-soundness, r=nagisa
Fix dropck issue of SyncOnceCell. Fixes #76367.
2 parents 6c6003a + e56ea68 commit 23e49dd

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

library/std/src/lazy.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod tests;
66
use crate::{
77
cell::{Cell, UnsafeCell},
88
fmt,
9+
marker::PhantomData,
910
mem::{self, MaybeUninit},
1011
ops::{Deref, Drop},
1112
panic::{RefUnwindSafe, UnwindSafe},
@@ -46,6 +47,26 @@ pub struct SyncOnceCell<T> {
4647
once: Once,
4748
// Whether or not the value is initialized is tracked by `state_and_queue`.
4849
value: UnsafeCell<MaybeUninit<T>>,
50+
/// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
51+
///
52+
/// ```compile_fail,E0597
53+
/// #![feature(once_cell)]
54+
///
55+
/// use std::lazy::SyncOnceCell;
56+
///
57+
/// struct A<'a>(&'a str);
58+
///
59+
/// impl<'a> Drop for A<'a> {
60+
/// fn drop(&mut self) {}
61+
/// }
62+
///
63+
/// let cell = SyncOnceCell::new();
64+
/// {
65+
/// let s = String::new();
66+
/// let _ = cell.set(A(&s));
67+
/// }
68+
/// ```
69+
_marker: PhantomData<T>,
4970
}
5071

5172
// Why do we need `T: Send`?
@@ -119,7 +140,11 @@ impl<T> SyncOnceCell<T> {
119140
/// Creates a new empty cell.
120141
#[unstable(feature = "once_cell", issue = "74465")]
121142
pub const fn new() -> SyncOnceCell<T> {
122-
SyncOnceCell { once: Once::new(), value: UnsafeCell::new(MaybeUninit::uninit()) }
143+
SyncOnceCell {
144+
once: Once::new(),
145+
value: UnsafeCell::new(MaybeUninit::uninit()),
146+
_marker: PhantomData,
147+
}
123148
}
124149

125150
/// Gets the reference to the underlying value.

0 commit comments

Comments
 (0)