1 //! Lazy values and one-time initialization of static data.
7 cell::{Cell, UnsafeCell},
12 panic::{RefUnwindSafe, UnwindSafe},
17 #[unstable(feature = "once_cell", issue = "74465")]
18 pub use core::lazy::*;
20 /// A synchronization primitive which can be written to only once.
22 /// This type is a thread-safe `OnceCell`.
27 /// #![feature(once_cell)]
29 /// use std::lazy::SyncOnceCell;
31 /// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
32 /// assert!(CELL.get().is_none());
34 /// std::thread::spawn(|| {
35 /// let value: &String = CELL.get_or_init(|| {
36 /// "Hello, World!".to_string()
38 /// assert_eq!(value, "Hello, World!");
39 /// }).join().unwrap();
41 /// let value: Option<&String> = CELL.get();
42 /// assert!(value.is_some());
43 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
45 #[unstable(feature = "once_cell", issue = "74465")]
46 pub struct SyncOnceCell<T> {
48 // Whether or not the value is initialized is tracked by `state_and_queue`.
49 value: UnsafeCell<MaybeUninit<T>>,
50 /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
52 /// ```compile_fail,E0597
53 /// #![feature(once_cell)]
55 /// use std::lazy::SyncOnceCell;
57 /// struct A<'a>(&'a str);
59 /// impl<'a> Drop for A<'a> {
60 /// fn drop(&mut self) {}
63 /// let cell = SyncOnceCell::new();
65 /// let s = String::new();
66 /// let _ = cell.set(A(&s));
69 _marker: PhantomData<T>,
72 // Why do we need `T: Send`?
73 // Thread A creates a `SyncOnceCell` and shares it with
74 // scoped thread B, which fills the cell, which is
75 // then destroyed by A. That is, destructor observes
77 #[unstable(feature = "once_cell", issue = "74465")]
78 unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
79 #[unstable(feature = "once_cell", issue = "74465")]
80 unsafe impl<T: Send> Send for SyncOnceCell<T> {}
82 #[unstable(feature = "once_cell", issue = "74465")]
83 impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
84 #[unstable(feature = "once_cell", issue = "74465")]
85 impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
87 #[unstable(feature = "once_cell", issue = "74465")]
88 impl<T> Default for SyncOnceCell<T> {
89 fn default() -> SyncOnceCell<T> {
94 #[unstable(feature = "once_cell", issue = "74465")]
95 impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 Some(v) => f.debug_tuple("Once").field(v).finish(),
99 None => f.write_str("Once(Uninit)"),
104 #[unstable(feature = "once_cell", issue = "74465")]
105 impl<T: Clone> Clone for SyncOnceCell<T> {
106 fn clone(&self) -> SyncOnceCell<T> {
107 let cell = Self::new();
108 if let Some(value) = self.get() {
109 match cell.set(value.clone()) {
111 Err(_) => unreachable!(),
118 #[unstable(feature = "once_cell", issue = "74465")]
119 impl<T> From<T> for SyncOnceCell<T> {
120 fn from(value: T) -> Self {
121 let cell = Self::new();
122 match cell.set(value) {
124 Err(_) => unreachable!(),
129 #[unstable(feature = "once_cell", issue = "74465")]
130 impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
131 fn eq(&self, other: &SyncOnceCell<T>) -> bool {
132 self.get() == other.get()
136 #[unstable(feature = "once_cell", issue = "74465")]
137 impl<T: Eq> Eq for SyncOnceCell<T> {}
139 impl<T> SyncOnceCell<T> {
140 /// Creates a new empty cell.
141 #[unstable(feature = "once_cell", issue = "74465")]
142 pub const fn new() -> SyncOnceCell<T> {
145 value: UnsafeCell::new(MaybeUninit::uninit()),
146 _marker: PhantomData,
150 /// Gets the reference to the underlying value.
152 /// Returns `None` if the cell is empty, or being initialized. This
153 /// method never blocks.
154 #[unstable(feature = "once_cell", issue = "74465")]
155 pub fn get(&self) -> Option<&T> {
156 if self.is_initialized() {
157 // Safe b/c checked is_initialized
158 Some(unsafe { self.get_unchecked() })
164 /// Gets the mutable reference to the underlying value.
166 /// Returns `None` if the cell is empty. This method never blocks.
167 #[unstable(feature = "once_cell", issue = "74465")]
168 pub fn get_mut(&mut self) -> Option<&mut T> {
169 if self.is_initialized() {
170 // Safe b/c checked is_initialized and we have a unique access
171 Some(unsafe { self.get_unchecked_mut() })
177 /// Sets the contents of this cell to `value`.
179 /// Returns `Ok(())` if the cell's value was updated.
184 /// #![feature(once_cell)]
186 /// use std::lazy::SyncOnceCell;
188 /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
191 /// assert!(CELL.get().is_none());
193 /// std::thread::spawn(|| {
194 /// assert_eq!(CELL.set(92), Ok(()));
195 /// }).join().unwrap();
197 /// assert_eq!(CELL.set(62), Err(62));
198 /// assert_eq!(CELL.get(), Some(&92));
201 #[unstable(feature = "once_cell", issue = "74465")]
202 pub fn set(&self, value: T) -> Result<(), T> {
203 let mut value = Some(value);
204 self.get_or_init(|| value.take().unwrap());
207 Some(value) => Err(value),
211 /// Gets the contents of the cell, initializing it with `f` if the cell
214 /// Many threads may call `get_or_init` concurrently with different
215 /// initializing functions, but it is guaranteed that only one function
216 /// will be executed.
220 /// If `f` panics, the panic is propagated to the caller, and the cell
221 /// remains uninitialized.
223 /// It is an error to reentrantly initialize the cell from `f`. The
224 /// exact outcome is unspecified. Current implementation deadlocks, but
225 /// this may be changed to a panic in the future.
230 /// #![feature(once_cell)]
232 /// use std::lazy::SyncOnceCell;
234 /// let cell = SyncOnceCell::new();
235 /// let value = cell.get_or_init(|| 92);
236 /// assert_eq!(value, &92);
237 /// let value = cell.get_or_init(|| unreachable!());
238 /// assert_eq!(value, &92);
240 #[unstable(feature = "once_cell", issue = "74465")]
241 pub fn get_or_init<F>(&self, f: F) -> &T
245 match self.get_or_try_init(|| Ok::<T, !>(f())) {
250 /// Gets the contents of the cell, initializing it with `f` if
251 /// the cell was empty. If the cell was empty and `f` failed, an
252 /// error is returned.
256 /// If `f` panics, the panic is propagated to the caller, and
257 /// the cell remains uninitialized.
259 /// It is an error to reentrantly initialize the cell from `f`.
260 /// The exact outcome is unspecified. Current implementation
261 /// deadlocks, but this may be changed to a panic in the future.
266 /// #![feature(once_cell)]
268 /// use std::lazy::SyncOnceCell;
270 /// let cell = SyncOnceCell::new();
271 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
272 /// assert!(cell.get().is_none());
273 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
276 /// assert_eq!(value, Ok(&92));
277 /// assert_eq!(cell.get(), Some(&92))
279 #[unstable(feature = "once_cell", issue = "74465")]
280 pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
282 F: FnOnce() -> Result<T, E>,
285 // NOTE: We need to perform an acquire on the state in this method
286 // in order to correctly synchronize `SyncLazy::force`. This is
287 // currently done by calling `self.get()`, which in turn calls
288 // `self.is_initialized()`, which in turn performs the acquire.
289 if let Some(value) = self.get() {
294 debug_assert!(self.is_initialized());
296 // SAFETY: The inner value has been initialized
297 Ok(unsafe { self.get_unchecked() })
300 /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
301 /// `None` if the cell was empty.
306 /// #![feature(once_cell)]
308 /// use std::lazy::SyncOnceCell;
310 /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
311 /// assert_eq!(cell.into_inner(), None);
313 /// let cell = SyncOnceCell::new();
314 /// cell.set("hello".to_string()).unwrap();
315 /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
317 #[unstable(feature = "once_cell", issue = "74465")]
318 pub fn into_inner(mut self) -> Option<T> {
322 /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
324 /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
326 /// Safety is guaranteed by requiring a mutable reference.
331 /// #![feature(once_cell)]
333 /// use std::lazy::SyncOnceCell;
335 /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
336 /// assert_eq!(cell.take(), None);
338 /// let mut cell = SyncOnceCell::new();
339 /// cell.set("hello".to_string()).unwrap();
340 /// assert_eq!(cell.take(), Some("hello".to_string()));
341 /// assert_eq!(cell.get(), None);
343 #[unstable(feature = "once_cell", issue = "74465")]
344 pub fn take(&mut self) -> Option<T> {
345 if self.is_initialized() {
346 self.once = Once::new();
347 // SAFETY: `self.value` is initialized and contains a valid `T`.
348 // `self.once` is reset, so `is_initialized()` will be false again
349 // which prevents the value from being read twice.
350 unsafe { Some((&mut *self.value.get()).assume_init_read()) }
357 fn is_initialized(&self) -> bool {
358 self.once.is_completed()
362 fn initialize<F, E>(&self, f: F) -> Result<(), E>
364 F: FnOnce() -> Result<T, E>,
366 let mut res: Result<(), E> = Ok(());
367 let slot = &self.value;
369 // Ignore poisoning from other threads
370 // If another thread panics, then we'll be able to run our closure
371 self.once.call_once_force(|p| {
374 unsafe { (&mut *slot.get()).write(value) };
379 // Treat the underlying `Once` as poisoned since we
380 // failed to initialize our value. Calls
388 /// Safety: The value must be initialized
389 unsafe fn get_unchecked(&self) -> &T {
390 debug_assert!(self.is_initialized());
391 (&*self.value.get()).assume_init_ref()
394 /// Safety: The value must be initialized
395 unsafe fn get_unchecked_mut(&mut self) -> &mut T {
396 debug_assert!(self.is_initialized());
397 (&mut *self.value.get()).assume_init_mut()
401 unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
403 if self.is_initialized() {
404 // Safety: The cell is initialized and being dropped, so it can't
405 // be accessed again. We also don't touch the `T` other than
406 // dropping it, which validates our usage of #[may_dangle].
407 unsafe { (&mut *self.value.get()).assume_init_drop() };
412 /// A value which is initialized on the first access.
414 /// This type is a thread-safe `Lazy`, and can be used in statics.
419 /// #![feature(once_cell)]
421 /// use std::collections::HashMap;
423 /// use std::lazy::SyncLazy;
425 /// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
426 /// println!("initializing");
427 /// let mut m = HashMap::new();
428 /// m.insert(13, "Spica".to_string());
429 /// m.insert(74, "Hoyten".to_string());
434 /// println!("ready");
435 /// std::thread::spawn(|| {
436 /// println!("{:?}", HASHMAP.get(&13));
437 /// }).join().unwrap();
438 /// println!("{:?}", HASHMAP.get(&74));
444 /// // Some("Hoyten")
447 #[unstable(feature = "once_cell", issue = "74465")]
448 pub struct SyncLazy<T, F = fn() -> T> {
449 cell: SyncOnceCell<T>,
450 init: Cell<Option<F>>,
453 #[unstable(feature = "once_cell", issue = "74465")]
454 impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
455 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456 f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
460 // We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
461 // to not impl `Sync` for `F`
462 // we do create a `&mut Option<F>` in `force`, but this is
463 // properly synchronized, so it only happens once
464 // so it also does not contribute to this impl.
465 #[unstable(feature = "once_cell", issue = "74465")]
466 unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
467 // auto-derived `Send` impl is OK.
469 #[unstable(feature = "once_cell", issue = "74465")]
470 impl<T, F: UnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
471 #[unstable(feature = "once_cell", issue = "74465")]
472 impl<T, F: UnwindSafe> UnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: UnwindSafe {}
474 impl<T, F> SyncLazy<T, F> {
475 /// Creates a new lazy value with the given initializing
477 #[unstable(feature = "once_cell", issue = "74465")]
478 pub const fn new(f: F) -> SyncLazy<T, F> {
479 SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
483 impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
484 /// Forces the evaluation of this lazy value and
485 /// returns a reference to result. This is equivalent
486 /// to the `Deref` impl, but is explicit.
491 /// #![feature(once_cell)]
493 /// use std::lazy::SyncLazy;
495 /// let lazy = SyncLazy::new(|| 92);
497 /// assert_eq!(SyncLazy::force(&lazy), &92);
498 /// assert_eq!(&*lazy, &92);
500 #[unstable(feature = "once_cell", issue = "74465")]
501 pub fn force(this: &SyncLazy<T, F>) -> &T {
502 this.cell.get_or_init(|| match this.init.take() {
504 None => panic!("Lazy instance has previously been poisoned"),
509 #[unstable(feature = "once_cell", issue = "74465")]
510 impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
512 fn deref(&self) -> &T {
513 SyncLazy::force(self)
517 #[unstable(feature = "once_cell", issue = "74465")]
518 impl<T: Default> Default for SyncLazy<T> {
519 /// Creates a new lazy value using `Default` as the initializing function.
520 fn default() -> SyncLazy<T> {
521 SyncLazy::new(T::default)