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