1 //! Lazy values and one-time initialization of static data.
7 cell::{Cell, UnsafeCell},
12 panic::{RefUnwindSafe, UnwindSafe},
18 #[unstable(feature = "once_cell", issue = "74465")]
19 pub use core::lazy::*;
21 /// A synchronization primitive which can be written to only once.
23 /// This type is a thread-safe `OnceCell`.
28 /// #![feature(once_cell)]
30 /// use std::lazy::SyncOnceCell;
32 /// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
33 /// assert!(CELL.get().is_none());
35 /// std::thread::spawn(|| {
36 /// let value: &String = CELL.get_or_init(|| {
37 /// "Hello, World!".to_string()
39 /// assert_eq!(value, "Hello, World!");
40 /// }).join().unwrap();
42 /// let value: Option<&String> = CELL.get();
43 /// assert!(value.is_some());
44 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
46 #[unstable(feature = "once_cell", issue = "74465")]
47 pub struct SyncOnceCell<T> {
49 // Whether or not the value is initialized is tracked by `state_and_queue`.
50 value: UnsafeCell<MaybeUninit<T>>,
51 /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
53 /// ```compile_fail,E0597
54 /// #![feature(once_cell)]
56 /// use std::lazy::SyncOnceCell;
58 /// struct A<'a>(&'a str);
60 /// impl<'a> Drop for A<'a> {
61 /// fn drop(&mut self) {}
64 /// let cell = SyncOnceCell::new();
66 /// let s = String::new();
67 /// let _ = cell.set(A(&s));
70 _marker: PhantomData<T>,
73 // Why do we need `T: Send`?
74 // Thread A creates a `SyncOnceCell` and shares it with
75 // scoped thread B, which fills the cell, which is
76 // then destroyed by A. That is, destructor observes
78 #[unstable(feature = "once_cell", issue = "74465")]
79 unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
80 #[unstable(feature = "once_cell", issue = "74465")]
81 unsafe impl<T: Send> Send for SyncOnceCell<T> {}
83 #[unstable(feature = "once_cell", issue = "74465")]
84 impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
85 #[unstable(feature = "once_cell", issue = "74465")]
86 impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
88 #[unstable(feature = "once_cell", issue = "74465")]
89 #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
90 impl<T> const Default for SyncOnceCell<T> {
91 /// Creates a new empty cell.
96 /// #![feature(once_cell)]
98 /// use std::lazy::SyncOnceCell;
101 /// assert_eq!(SyncOnceCell::<()>::new(), SyncOnceCell::default());
104 fn default() -> SyncOnceCell<T> {
109 #[unstable(feature = "once_cell", issue = "74465")]
110 impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 Some(v) => f.debug_tuple("Once").field(v).finish(),
114 None => f.write_str("Once(Uninit)"),
119 #[unstable(feature = "once_cell", issue = "74465")]
120 impl<T: Clone> Clone for SyncOnceCell<T> {
121 fn clone(&self) -> SyncOnceCell<T> {
122 let cell = Self::new();
123 if let Some(value) = self.get() {
124 match cell.set(value.clone()) {
126 Err(_) => unreachable!(),
133 #[unstable(feature = "once_cell", issue = "74465")]
134 impl<T> From<T> for SyncOnceCell<T> {
135 /// Create a new cell with its contents set to `value`.
140 /// #![feature(once_cell)]
142 /// use std::lazy::SyncOnceCell;
144 /// # fn main() -> Result<(), i32> {
145 /// let a = SyncOnceCell::from(3);
146 /// let b = SyncOnceCell::new();
148 /// assert_eq!(a, b);
152 fn from(value: T) -> Self {
153 let cell = Self::new();
154 match cell.set(value) {
156 Err(_) => unreachable!(),
161 #[unstable(feature = "once_cell", issue = "74465")]
162 impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
163 fn eq(&self, other: &SyncOnceCell<T>) -> bool {
164 self.get() == other.get()
168 #[unstable(feature = "once_cell", issue = "74465")]
169 impl<T: Eq> Eq for SyncOnceCell<T> {}
171 impl<T> SyncOnceCell<T> {
172 /// Creates a new empty cell.
173 #[unstable(feature = "once_cell", issue = "74465")]
174 pub const fn new() -> SyncOnceCell<T> {
177 value: UnsafeCell::new(MaybeUninit::uninit()),
178 _marker: PhantomData,
182 /// Gets the reference to the underlying value.
184 /// Returns `None` if the cell is empty, or being initialized. This
185 /// method never blocks.
186 #[unstable(feature = "once_cell", issue = "74465")]
187 pub fn get(&self) -> Option<&T> {
188 if self.is_initialized() {
189 // Safe b/c checked is_initialized
190 Some(unsafe { self.get_unchecked() })
196 /// Gets the mutable reference to the underlying value.
198 /// Returns `None` if the cell is empty. This method never blocks.
199 #[unstable(feature = "once_cell", issue = "74465")]
200 pub fn get_mut(&mut self) -> Option<&mut T> {
201 if self.is_initialized() {
202 // Safe b/c checked is_initialized and we have a unique access
203 Some(unsafe { self.get_unchecked_mut() })
209 /// Sets the contents of this cell to `value`.
211 /// May block if another thread is currently attempting to initialize the cell. The cell is
212 /// guaranteed to contain a value when set returns, though not necessarily the one provided.
214 /// Returns `Ok(())` if the cell's value was set by this call.
219 /// #![feature(once_cell)]
221 /// use std::lazy::SyncOnceCell;
223 /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
226 /// assert!(CELL.get().is_none());
228 /// std::thread::spawn(|| {
229 /// assert_eq!(CELL.set(92), Ok(()));
230 /// }).join().unwrap();
232 /// assert_eq!(CELL.set(62), Err(62));
233 /// assert_eq!(CELL.get(), Some(&92));
236 #[unstable(feature = "once_cell", issue = "74465")]
237 pub fn set(&self, value: T) -> Result<(), T> {
238 let mut value = Some(value);
239 self.get_or_init(|| value.take().unwrap());
242 Some(value) => Err(value),
246 /// Gets the contents of the cell, initializing it with `f` if the cell
249 /// Many threads may call `get_or_init` concurrently with different
250 /// initializing functions, but it is guaranteed that only one function
251 /// will be executed.
255 /// If `f` panics, the panic is propagated to the caller, and the cell
256 /// remains uninitialized.
258 /// It is an error to reentrantly initialize the cell from `f`. The
259 /// exact outcome is unspecified. Current implementation deadlocks, but
260 /// this may be changed to a panic in the future.
265 /// #![feature(once_cell)]
267 /// use std::lazy::SyncOnceCell;
269 /// let cell = SyncOnceCell::new();
270 /// let value = cell.get_or_init(|| 92);
271 /// assert_eq!(value, &92);
272 /// let value = cell.get_or_init(|| unreachable!());
273 /// assert_eq!(value, &92);
275 #[unstable(feature = "once_cell", issue = "74465")]
276 pub fn get_or_init<F>(&self, f: F) -> &T
280 match self.get_or_try_init(|| Ok::<T, !>(f())) {
285 /// Gets the contents of the cell, initializing it with `f` if
286 /// the cell was empty. If the cell was empty and `f` failed, an
287 /// error is returned.
291 /// If `f` panics, the panic is propagated to the caller, and
292 /// the cell remains uninitialized.
294 /// It is an error to reentrantly initialize the cell from `f`.
295 /// The exact outcome is unspecified. Current implementation
296 /// deadlocks, but this may be changed to a panic in the future.
301 /// #![feature(once_cell)]
303 /// use std::lazy::SyncOnceCell;
305 /// let cell = SyncOnceCell::new();
306 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
307 /// assert!(cell.get().is_none());
308 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
311 /// assert_eq!(value, Ok(&92));
312 /// assert_eq!(cell.get(), Some(&92))
314 #[unstable(feature = "once_cell", issue = "74465")]
315 pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
317 F: FnOnce() -> Result<T, E>,
320 // NOTE: We need to perform an acquire on the state in this method
321 // in order to correctly synchronize `SyncLazy::force`. This is
322 // currently done by calling `self.get()`, which in turn calls
323 // `self.is_initialized()`, which in turn performs the acquire.
324 if let Some(value) = self.get() {
329 debug_assert!(self.is_initialized());
331 // SAFETY: The inner value has been initialized
332 Ok(unsafe { self.get_unchecked() })
335 /// Internal-only API that gets the contents of the cell, initializing it
336 /// in two steps with `f` and `g` if the cell was empty.
338 /// `f` is called to construct the value, which is then moved into the cell
339 /// and given as a (pinned) mutable reference to `g` to finish
342 /// This allows `g` to inspect an manipulate the value after it has been
343 /// moved into its final place in the cell, but before the cell is
344 /// considered initialized.
348 /// If `f` or `g` panics, the panic is propagated to the caller, and the
349 /// cell remains uninitialized.
351 /// With the current implementation, if `g` panics, the value from `f` will
352 /// not be dropped. This should probably be fixed if this is ever used for
353 /// a type where this matters.
355 /// It is an error to reentrantly initialize the cell from `f`. The exact
356 /// outcome is unspecified. Current implementation deadlocks, but this may
357 /// be changed to a panic in the future.
358 pub(crate) fn get_or_init_pin<F, G>(self: Pin<&Self>, f: F, g: G) -> Pin<&T>
361 G: FnOnce(Pin<&mut T>),
363 if let Some(value) = self.get_ref().get() {
364 // SAFETY: The inner value was already initialized, and will not be
366 return unsafe { Pin::new_unchecked(value) };
369 let slot = &self.value;
371 // Ignore poisoning from other threads
372 // If another thread panics, then we'll be able to run our closure
373 self.once.call_once_force(|_| {
375 // SAFETY: We use the Once (self.once) to guarantee unique access
376 // to the UnsafeCell (slot).
377 let value: &mut T = unsafe { (&mut *slot.get()).write(value) };
378 // SAFETY: The value has been written to its final place in
379 // self.value. We do not to move it anymore, which we promise here
380 // with a Pin<&mut T>.
381 g(unsafe { Pin::new_unchecked(value) });
384 // SAFETY: The inner value has been initialized, and will not be moved
386 unsafe { Pin::new_unchecked(self.get_ref().get_unchecked()) }
389 /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
390 /// `None` if the cell was empty.
395 /// #![feature(once_cell)]
397 /// use std::lazy::SyncOnceCell;
399 /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
400 /// assert_eq!(cell.into_inner(), None);
402 /// let cell = SyncOnceCell::new();
403 /// cell.set("hello".to_string()).unwrap();
404 /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
406 #[unstable(feature = "once_cell", issue = "74465")]
407 pub fn into_inner(mut self) -> Option<T> {
411 /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
413 /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
415 /// Safety is guaranteed by requiring a mutable reference.
420 /// #![feature(once_cell)]
422 /// use std::lazy::SyncOnceCell;
424 /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
425 /// assert_eq!(cell.take(), None);
427 /// let mut cell = SyncOnceCell::new();
428 /// cell.set("hello".to_string()).unwrap();
429 /// assert_eq!(cell.take(), Some("hello".to_string()));
430 /// assert_eq!(cell.get(), None);
432 #[unstable(feature = "once_cell", issue = "74465")]
433 pub fn take(&mut self) -> Option<T> {
434 if self.is_initialized() {
435 self.once = Once::new();
436 // SAFETY: `self.value` is initialized and contains a valid `T`.
437 // `self.once` is reset, so `is_initialized()` will be false again
438 // which prevents the value from being read twice.
439 unsafe { Some((&mut *self.value.get()).assume_init_read()) }
446 fn is_initialized(&self) -> bool {
447 self.once.is_completed()
451 fn initialize<F, E>(&self, f: F) -> Result<(), E>
453 F: FnOnce() -> Result<T, E>,
455 let mut res: Result<(), E> = Ok(());
456 let slot = &self.value;
458 // Ignore poisoning from other threads
459 // If another thread panics, then we'll be able to run our closure
460 self.once.call_once_force(|p| {
463 unsafe { (&mut *slot.get()).write(value) };
468 // Treat the underlying `Once` as poisoned since we
469 // failed to initialize our value. Calls
479 /// The value must be initialized
480 unsafe fn get_unchecked(&self) -> &T {
481 debug_assert!(self.is_initialized());
482 (&*self.value.get()).assume_init_ref()
487 /// The value must be initialized
488 unsafe fn get_unchecked_mut(&mut self) -> &mut T {
489 debug_assert!(self.is_initialized());
490 (&mut *self.value.get()).assume_init_mut()
494 unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
496 if self.is_initialized() {
497 // SAFETY: The cell is initialized and being dropped, so it can't
498 // be accessed again. We also don't touch the `T` other than
499 // dropping it, which validates our usage of #[may_dangle].
500 unsafe { (&mut *self.value.get()).assume_init_drop() };
505 /// A value which is initialized on the first access.
507 /// This type is a thread-safe `Lazy`, and can be used in statics.
512 /// #![feature(once_cell)]
514 /// use std::collections::HashMap;
516 /// use std::lazy::SyncLazy;
518 /// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
519 /// println!("initializing");
520 /// let mut m = HashMap::new();
521 /// m.insert(13, "Spica".to_string());
522 /// m.insert(74, "Hoyten".to_string());
527 /// println!("ready");
528 /// std::thread::spawn(|| {
529 /// println!("{:?}", HASHMAP.get(&13));
530 /// }).join().unwrap();
531 /// println!("{:?}", HASHMAP.get(&74));
537 /// // Some("Hoyten")
540 #[unstable(feature = "once_cell", issue = "74465")]
541 pub struct SyncLazy<T, F = fn() -> T> {
542 cell: SyncOnceCell<T>,
543 init: Cell<Option<F>>,
546 #[unstable(feature = "once_cell", issue = "74465")]
547 impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
548 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
549 f.debug_struct("Lazy").field("cell", &self.cell).finish_non_exhaustive()
553 // We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
554 // to not impl `Sync` for `F`
555 // we do create a `&mut Option<F>` in `force`, but this is
556 // properly synchronized, so it only happens once
557 // so it also does not contribute to this impl.
558 #[unstable(feature = "once_cell", issue = "74465")]
559 unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
560 // auto-derived `Send` impl is OK.
562 #[unstable(feature = "once_cell", issue = "74465")]
563 impl<T, F: UnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
564 #[unstable(feature = "once_cell", issue = "74465")]
565 impl<T, F: UnwindSafe> UnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: UnwindSafe {}
567 impl<T, F> SyncLazy<T, F> {
568 /// Creates a new lazy value with the given initializing
570 #[unstable(feature = "once_cell", issue = "74465")]
571 pub const fn new(f: F) -> SyncLazy<T, F> {
572 SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
576 impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
577 /// Forces the evaluation of this lazy value and
578 /// returns a reference to result. This is equivalent
579 /// to the `Deref` impl, but is explicit.
584 /// #![feature(once_cell)]
586 /// use std::lazy::SyncLazy;
588 /// let lazy = SyncLazy::new(|| 92);
590 /// assert_eq!(SyncLazy::force(&lazy), &92);
591 /// assert_eq!(&*lazy, &92);
593 #[unstable(feature = "once_cell", issue = "74465")]
594 pub fn force(this: &SyncLazy<T, F>) -> &T {
595 this.cell.get_or_init(|| match this.init.take() {
597 None => panic!("Lazy instance has previously been poisoned"),
602 #[unstable(feature = "once_cell", issue = "74465")]
603 impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
605 fn deref(&self) -> &T {
606 SyncLazy::force(self)
610 #[unstable(feature = "once_cell", issue = "74465")]
611 impl<T: Default> Default for SyncLazy<T> {
612 /// Creates a new lazy value using `Default` as the initializing function.
613 fn default() -> SyncLazy<T> {
614 SyncLazy::new(T::default)