]> git.lizzy.rs Git - rust.git/blob - library/std/src/lazy.rs
Rollup merge of #93824 - Amanieu:stable_cfg_target_has_atomic, r=davidtwco
[rust.git] / library / std / src / lazy.rs
1 //! Lazy values and one-time initialization of static data.
2
3 #[cfg(test)]
4 mod tests;
5
6 use crate::{
7     cell::{Cell, UnsafeCell},
8     fmt,
9     marker::PhantomData,
10     mem::MaybeUninit,
11     ops::{Deref, Drop},
12     panic::{RefUnwindSafe, UnwindSafe},
13     pin::Pin,
14     sync::Once,
15 };
16
17 #[doc(inline)]
18 #[unstable(feature = "once_cell", issue = "74465")]
19 pub use core::lazy::*;
20
21 /// A synchronization primitive which can be written to only once.
22 ///
23 /// This type is a thread-safe `OnceCell`.
24 ///
25 /// # Examples
26 ///
27 /// ```
28 /// #![feature(once_cell)]
29 ///
30 /// use std::lazy::SyncOnceCell;
31 ///
32 /// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
33 /// assert!(CELL.get().is_none());
34 ///
35 /// std::thread::spawn(|| {
36 ///     let value: &String = CELL.get_or_init(|| {
37 ///         "Hello, World!".to_string()
38 ///     });
39 ///     assert_eq!(value, "Hello, World!");
40 /// }).join().unwrap();
41 ///
42 /// let value: Option<&String> = CELL.get();
43 /// assert!(value.is_some());
44 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
45 /// ```
46 #[unstable(feature = "once_cell", issue = "74465")]
47 pub struct SyncOnceCell<T> {
48     once: Once,
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.
52     ///
53     /// ```compile_fail,E0597
54     /// #![feature(once_cell)]
55     ///
56     /// use std::lazy::SyncOnceCell;
57     ///
58     /// struct A<'a>(&'a str);
59     ///
60     /// impl<'a> Drop for A<'a> {
61     ///     fn drop(&mut self) {}
62     /// }
63     ///
64     /// let cell = SyncOnceCell::new();
65     /// {
66     ///     let s = String::new();
67     ///     let _ = cell.set(A(&s));
68     /// }
69     /// ```
70     _marker: PhantomData<T>,
71 }
72
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
77 // a sent value.
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> {}
82
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> {}
87
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.
92     ///
93     /// # Example
94     ///
95     /// ```
96     /// #![feature(once_cell)]
97     ///
98     /// use std::lazy::SyncOnceCell;
99     ///
100     /// fn main() {
101     ///     assert_eq!(SyncOnceCell::<()>::new(), SyncOnceCell::default());
102     /// }
103     /// ```
104     fn default() -> SyncOnceCell<T> {
105         SyncOnceCell::new()
106     }
107 }
108
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 {
112         match self.get() {
113             Some(v) => f.debug_tuple("Once").field(v).finish(),
114             None => f.write_str("Once(Uninit)"),
115         }
116     }
117 }
118
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()) {
125                 Ok(()) => (),
126                 Err(_) => unreachable!(),
127             }
128         }
129         cell
130     }
131 }
132
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`.
136     ///
137     /// # Example
138     ///
139     /// ```
140     /// #![feature(once_cell)]
141     ///
142     /// use std::lazy::SyncOnceCell;
143     ///
144     /// # fn main() -> Result<(), i32> {
145     /// let a = SyncOnceCell::from(3);
146     /// let b = SyncOnceCell::new();
147     /// b.set(3)?;
148     /// assert_eq!(a, b);
149     /// Ok(())
150     /// # }
151     /// ```
152     fn from(value: T) -> Self {
153         let cell = Self::new();
154         match cell.set(value) {
155             Ok(()) => cell,
156             Err(_) => unreachable!(),
157         }
158     }
159 }
160
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()
165     }
166 }
167
168 #[unstable(feature = "once_cell", issue = "74465")]
169 impl<T: Eq> Eq for SyncOnceCell<T> {}
170
171 impl<T> SyncOnceCell<T> {
172     /// Creates a new empty cell.
173     #[unstable(feature = "once_cell", issue = "74465")]
174     #[must_use]
175     pub const fn new() -> SyncOnceCell<T> {
176         SyncOnceCell {
177             once: Once::new(),
178             value: UnsafeCell::new(MaybeUninit::uninit()),
179             _marker: PhantomData,
180         }
181     }
182
183     /// Gets the reference to the underlying value.
184     ///
185     /// Returns `None` if the cell is empty, or being initialized. This
186     /// method never blocks.
187     #[unstable(feature = "once_cell", issue = "74465")]
188     pub fn get(&self) -> Option<&T> {
189         if self.is_initialized() {
190             // Safe b/c checked is_initialized
191             Some(unsafe { self.get_unchecked() })
192         } else {
193             None
194         }
195     }
196
197     /// Gets the mutable reference to the underlying value.
198     ///
199     /// Returns `None` if the cell is empty. This method never blocks.
200     #[unstable(feature = "once_cell", issue = "74465")]
201     pub fn get_mut(&mut self) -> Option<&mut T> {
202         if self.is_initialized() {
203             // Safe b/c checked is_initialized and we have a unique access
204             Some(unsafe { self.get_unchecked_mut() })
205         } else {
206             None
207         }
208     }
209
210     /// Sets the contents of this cell to `value`.
211     ///
212     /// May block if another thread is currently attempting to initialize the cell. The cell is
213     /// guaranteed to contain a value when set returns, though not necessarily the one provided.
214     ///
215     /// Returns `Ok(())` if the cell's value was set by this call.
216     ///
217     /// # Examples
218     ///
219     /// ```
220     /// #![feature(once_cell)]
221     ///
222     /// use std::lazy::SyncOnceCell;
223     ///
224     /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
225     ///
226     /// fn main() {
227     ///     assert!(CELL.get().is_none());
228     ///
229     ///     std::thread::spawn(|| {
230     ///         assert_eq!(CELL.set(92), Ok(()));
231     ///     }).join().unwrap();
232     ///
233     ///     assert_eq!(CELL.set(62), Err(62));
234     ///     assert_eq!(CELL.get(), Some(&92));
235     /// }
236     /// ```
237     #[unstable(feature = "once_cell", issue = "74465")]
238     pub fn set(&self, value: T) -> Result<(), T> {
239         let mut value = Some(value);
240         self.get_or_init(|| value.take().unwrap());
241         match value {
242             None => Ok(()),
243             Some(value) => Err(value),
244         }
245     }
246
247     /// Gets the contents of the cell, initializing it with `f` if the cell
248     /// was empty.
249     ///
250     /// Many threads may call `get_or_init` concurrently with different
251     /// initializing functions, but it is guaranteed that only one function
252     /// will be executed.
253     ///
254     /// # Panics
255     ///
256     /// If `f` panics, the panic is propagated to the caller, and the cell
257     /// remains uninitialized.
258     ///
259     /// It is an error to reentrantly initialize the cell from `f`. The
260     /// exact outcome is unspecified. Current implementation deadlocks, but
261     /// this may be changed to a panic in the future.
262     ///
263     /// # Examples
264     ///
265     /// ```
266     /// #![feature(once_cell)]
267     ///
268     /// use std::lazy::SyncOnceCell;
269     ///
270     /// let cell = SyncOnceCell::new();
271     /// let value = cell.get_or_init(|| 92);
272     /// assert_eq!(value, &92);
273     /// let value = cell.get_or_init(|| unreachable!());
274     /// assert_eq!(value, &92);
275     /// ```
276     #[unstable(feature = "once_cell", issue = "74465")]
277     pub fn get_or_init<F>(&self, f: F) -> &T
278     where
279         F: FnOnce() -> T,
280     {
281         match self.get_or_try_init(|| Ok::<T, !>(f())) {
282             Ok(val) => val,
283         }
284     }
285
286     /// Gets the contents of the cell, initializing it with `f` if
287     /// the cell was empty. If the cell was empty and `f` failed, an
288     /// error is returned.
289     ///
290     /// # Panics
291     ///
292     /// If `f` panics, the panic is propagated to the caller, and
293     /// the cell remains uninitialized.
294     ///
295     /// It is an error to reentrantly initialize the cell from `f`.
296     /// The exact outcome is unspecified. Current implementation
297     /// deadlocks, but this may be changed to a panic in the future.
298     ///
299     /// # Examples
300     ///
301     /// ```
302     /// #![feature(once_cell)]
303     ///
304     /// use std::lazy::SyncOnceCell;
305     ///
306     /// let cell = SyncOnceCell::new();
307     /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
308     /// assert!(cell.get().is_none());
309     /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
310     ///     Ok(92)
311     /// });
312     /// assert_eq!(value, Ok(&92));
313     /// assert_eq!(cell.get(), Some(&92))
314     /// ```
315     #[unstable(feature = "once_cell", issue = "74465")]
316     pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
317     where
318         F: FnOnce() -> Result<T, E>,
319     {
320         // Fast path check
321         // NOTE: We need to perform an acquire on the state in this method
322         // in order to correctly synchronize `SyncLazy::force`. This is
323         // currently done by calling `self.get()`, which in turn calls
324         // `self.is_initialized()`, which in turn performs the acquire.
325         if let Some(value) = self.get() {
326             return Ok(value);
327         }
328         self.initialize(f)?;
329
330         debug_assert!(self.is_initialized());
331
332         // SAFETY: The inner value has been initialized
333         Ok(unsafe { self.get_unchecked() })
334     }
335
336     /// Internal-only API that gets the contents of the cell, initializing it
337     /// in two steps with `f` and `g` if the cell was empty.
338     ///
339     /// `f` is called to construct the value, which is then moved into the cell
340     /// and given as a (pinned) mutable reference to `g` to finish
341     /// initialization.
342     ///
343     /// This allows `g` to inspect an manipulate the value after it has been
344     /// moved into its final place in the cell, but before the cell is
345     /// considered initialized.
346     ///
347     /// # Panics
348     ///
349     /// If `f` or `g` panics, the panic is propagated to the caller, and the
350     /// cell remains uninitialized.
351     ///
352     /// With the current implementation, if `g` panics, the value from `f` will
353     /// not be dropped. This should probably be fixed if this is ever used for
354     /// a type where this matters.
355     ///
356     /// It is an error to reentrantly initialize the cell from `f`. The exact
357     /// outcome is unspecified. Current implementation deadlocks, but this may
358     /// be changed to a panic in the future.
359     pub(crate) fn get_or_init_pin<F, G>(self: Pin<&Self>, f: F, g: G) -> Pin<&T>
360     where
361         F: FnOnce() -> T,
362         G: FnOnce(Pin<&mut T>),
363     {
364         if let Some(value) = self.get_ref().get() {
365             // SAFETY: The inner value was already initialized, and will not be
366             // moved anymore.
367             return unsafe { Pin::new_unchecked(value) };
368         }
369
370         let slot = &self.value;
371
372         // Ignore poisoning from other threads
373         // If another thread panics, then we'll be able to run our closure
374         self.once.call_once_force(|_| {
375             let value = f();
376             // SAFETY: We use the Once (self.once) to guarantee unique access
377             // to the UnsafeCell (slot).
378             let value: &mut T = unsafe { (&mut *slot.get()).write(value) };
379             // SAFETY: The value has been written to its final place in
380             // self.value. We do not to move it anymore, which we promise here
381             // with a Pin<&mut T>.
382             g(unsafe { Pin::new_unchecked(value) });
383         });
384
385         // SAFETY: The inner value has been initialized, and will not be moved
386         // anymore.
387         unsafe { Pin::new_unchecked(self.get_ref().get_unchecked()) }
388     }
389
390     /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
391     /// `None` if the cell was empty.
392     ///
393     /// # Examples
394     ///
395     /// ```
396     /// #![feature(once_cell)]
397     ///
398     /// use std::lazy::SyncOnceCell;
399     ///
400     /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
401     /// assert_eq!(cell.into_inner(), None);
402     ///
403     /// let cell = SyncOnceCell::new();
404     /// cell.set("hello".to_string()).unwrap();
405     /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
406     /// ```
407     #[unstable(feature = "once_cell", issue = "74465")]
408     pub fn into_inner(mut self) -> Option<T> {
409         self.take()
410     }
411
412     /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
413     ///
414     /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
415     ///
416     /// Safety is guaranteed by requiring a mutable reference.
417     ///
418     /// # Examples
419     ///
420     /// ```
421     /// #![feature(once_cell)]
422     ///
423     /// use std::lazy::SyncOnceCell;
424     ///
425     /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
426     /// assert_eq!(cell.take(), None);
427     ///
428     /// let mut cell = SyncOnceCell::new();
429     /// cell.set("hello".to_string()).unwrap();
430     /// assert_eq!(cell.take(), Some("hello".to_string()));
431     /// assert_eq!(cell.get(), None);
432     /// ```
433     #[unstable(feature = "once_cell", issue = "74465")]
434     pub fn take(&mut self) -> Option<T> {
435         if self.is_initialized() {
436             self.once = Once::new();
437             // SAFETY: `self.value` is initialized and contains a valid `T`.
438             // `self.once` is reset, so `is_initialized()` will be false again
439             // which prevents the value from being read twice.
440             unsafe { Some((&mut *self.value.get()).assume_init_read()) }
441         } else {
442             None
443         }
444     }
445
446     #[inline]
447     fn is_initialized(&self) -> bool {
448         self.once.is_completed()
449     }
450
451     #[cold]
452     fn initialize<F, E>(&self, f: F) -> Result<(), E>
453     where
454         F: FnOnce() -> Result<T, E>,
455     {
456         let mut res: Result<(), E> = Ok(());
457         let slot = &self.value;
458
459         // Ignore poisoning from other threads
460         // If another thread panics, then we'll be able to run our closure
461         self.once.call_once_force(|p| {
462             match f() {
463                 Ok(value) => {
464                     unsafe { (&mut *slot.get()).write(value) };
465                 }
466                 Err(e) => {
467                     res = Err(e);
468
469                     // Treat the underlying `Once` as poisoned since we
470                     // failed to initialize our value. Calls
471                     p.poison();
472                 }
473             }
474         });
475         res
476     }
477
478     /// # Safety
479     ///
480     /// The value must be initialized
481     unsafe fn get_unchecked(&self) -> &T {
482         debug_assert!(self.is_initialized());
483         (&*self.value.get()).assume_init_ref()
484     }
485
486     /// # Safety
487     ///
488     /// The value must be initialized
489     unsafe fn get_unchecked_mut(&mut self) -> &mut T {
490         debug_assert!(self.is_initialized());
491         (&mut *self.value.get()).assume_init_mut()
492     }
493 }
494
495 unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
496     fn drop(&mut self) {
497         if self.is_initialized() {
498             // SAFETY: The cell is initialized and being dropped, so it can't
499             // be accessed again. We also don't touch the `T` other than
500             // dropping it, which validates our usage of #[may_dangle].
501             unsafe { (&mut *self.value.get()).assume_init_drop() };
502         }
503     }
504 }
505
506 /// A value which is initialized on the first access.
507 ///
508 /// This type is a thread-safe `Lazy`, and can be used in statics.
509 ///
510 /// # Examples
511 ///
512 /// ```
513 /// #![feature(once_cell)]
514 ///
515 /// use std::collections::HashMap;
516 ///
517 /// use std::lazy::SyncLazy;
518 ///
519 /// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
520 ///     println!("initializing");
521 ///     let mut m = HashMap::new();
522 ///     m.insert(13, "Spica".to_string());
523 ///     m.insert(74, "Hoyten".to_string());
524 ///     m
525 /// });
526 ///
527 /// fn main() {
528 ///     println!("ready");
529 ///     std::thread::spawn(|| {
530 ///         println!("{:?}", HASHMAP.get(&13));
531 ///     }).join().unwrap();
532 ///     println!("{:?}", HASHMAP.get(&74));
533 ///
534 ///     // Prints:
535 ///     //   ready
536 ///     //   initializing
537 ///     //   Some("Spica")
538 ///     //   Some("Hoyten")
539 /// }
540 /// ```
541 #[unstable(feature = "once_cell", issue = "74465")]
542 pub struct SyncLazy<T, F = fn() -> T> {
543     cell: SyncOnceCell<T>,
544     init: Cell<Option<F>>,
545 }
546
547 #[unstable(feature = "once_cell", issue = "74465")]
548 impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
549     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
550         f.debug_struct("Lazy").field("cell", &self.cell).finish_non_exhaustive()
551     }
552 }
553
554 // We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
555 // to not impl `Sync` for `F`
556 // we do create a `&mut Option<F>` in `force`, but this is
557 // properly synchronized, so it only happens once
558 // so it also does not contribute to this impl.
559 #[unstable(feature = "once_cell", issue = "74465")]
560 unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
561 // auto-derived `Send` impl is OK.
562
563 #[unstable(feature = "once_cell", issue = "74465")]
564 impl<T, F: UnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
565 #[unstable(feature = "once_cell", issue = "74465")]
566 impl<T, F: UnwindSafe> UnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: UnwindSafe {}
567
568 impl<T, F> SyncLazy<T, F> {
569     /// Creates a new lazy value with the given initializing
570     /// function.
571     #[unstable(feature = "once_cell", issue = "74465")]
572     pub const fn new(f: F) -> SyncLazy<T, F> {
573         SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
574     }
575 }
576
577 impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
578     /// Forces the evaluation of this lazy value and
579     /// returns a reference to result. This is equivalent
580     /// to the `Deref` impl, but is explicit.
581     ///
582     /// # Examples
583     ///
584     /// ```
585     /// #![feature(once_cell)]
586     ///
587     /// use std::lazy::SyncLazy;
588     ///
589     /// let lazy = SyncLazy::new(|| 92);
590     ///
591     /// assert_eq!(SyncLazy::force(&lazy), &92);
592     /// assert_eq!(&*lazy, &92);
593     /// ```
594     #[unstable(feature = "once_cell", issue = "74465")]
595     pub fn force(this: &SyncLazy<T, F>) -> &T {
596         this.cell.get_or_init(|| match this.init.take() {
597             Some(f) => f(),
598             None => panic!("Lazy instance has previously been poisoned"),
599         })
600     }
601 }
602
603 #[unstable(feature = "once_cell", issue = "74465")]
604 impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
605     type Target = T;
606     fn deref(&self) -> &T {
607         SyncLazy::force(self)
608     }
609 }
610
611 #[unstable(feature = "once_cell", issue = "74465")]
612 impl<T: Default> Default for SyncLazy<T> {
613     /// Creates a new lazy value using `Default` as the initializing function.
614     fn default() -> SyncLazy<T> {
615         SyncLazy::new(T::default)
616     }
617 }