]> git.lizzy.rs Git - rust.git/blob - library/std/src/lazy.rs
Stabilize try_reserve
[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     pub const fn new() -> SyncOnceCell<T> {
175         SyncOnceCell {
176             once: Once::new(),
177             value: UnsafeCell::new(MaybeUninit::uninit()),
178             _marker: PhantomData,
179         }
180     }
181
182     /// Gets the reference to the underlying value.
183     ///
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() })
191         } else {
192             None
193         }
194     }
195
196     /// Gets the mutable reference to the underlying value.
197     ///
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() })
204         } else {
205             None
206         }
207     }
208
209     /// Sets the contents of this cell to `value`.
210     ///
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.
213     ///
214     /// Returns `Ok(())` if the cell's value was set by this call.
215     ///
216     /// # Examples
217     ///
218     /// ```
219     /// #![feature(once_cell)]
220     ///
221     /// use std::lazy::SyncOnceCell;
222     ///
223     /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
224     ///
225     /// fn main() {
226     ///     assert!(CELL.get().is_none());
227     ///
228     ///     std::thread::spawn(|| {
229     ///         assert_eq!(CELL.set(92), Ok(()));
230     ///     }).join().unwrap();
231     ///
232     ///     assert_eq!(CELL.set(62), Err(62));
233     ///     assert_eq!(CELL.get(), Some(&92));
234     /// }
235     /// ```
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());
240         match value {
241             None => Ok(()),
242             Some(value) => Err(value),
243         }
244     }
245
246     /// Gets the contents of the cell, initializing it with `f` if the cell
247     /// was empty.
248     ///
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.
252     ///
253     /// # Panics
254     ///
255     /// If `f` panics, the panic is propagated to the caller, and the cell
256     /// remains uninitialized.
257     ///
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.
261     ///
262     /// # Examples
263     ///
264     /// ```
265     /// #![feature(once_cell)]
266     ///
267     /// use std::lazy::SyncOnceCell;
268     ///
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);
274     /// ```
275     #[unstable(feature = "once_cell", issue = "74465")]
276     pub fn get_or_init<F>(&self, f: F) -> &T
277     where
278         F: FnOnce() -> T,
279     {
280         match self.get_or_try_init(|| Ok::<T, !>(f())) {
281             Ok(val) => val,
282         }
283     }
284
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.
288     ///
289     /// # Panics
290     ///
291     /// If `f` panics, the panic is propagated to the caller, and
292     /// the cell remains uninitialized.
293     ///
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.
297     ///
298     /// # Examples
299     ///
300     /// ```
301     /// #![feature(once_cell)]
302     ///
303     /// use std::lazy::SyncOnceCell;
304     ///
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, ()> {
309     ///     Ok(92)
310     /// });
311     /// assert_eq!(value, Ok(&92));
312     /// assert_eq!(cell.get(), Some(&92))
313     /// ```
314     #[unstable(feature = "once_cell", issue = "74465")]
315     pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
316     where
317         F: FnOnce() -> Result<T, E>,
318     {
319         // Fast path check
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() {
325             return Ok(value);
326         }
327         self.initialize(f)?;
328
329         debug_assert!(self.is_initialized());
330
331         // SAFETY: The inner value has been initialized
332         Ok(unsafe { self.get_unchecked() })
333     }
334
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.
337     ///
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
340     /// initialization.
341     ///
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.
345     ///
346     /// # Panics
347     ///
348     /// If `f` or `g` panics, the panic is propagated to the caller, and the
349     /// cell remains uninitialized.
350     ///
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.
354     ///
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>
359     where
360         F: FnOnce() -> T,
361         G: FnOnce(Pin<&mut T>),
362     {
363         if let Some(value) = self.get_ref().get() {
364             // SAFETY: The inner value was already initialized, and will not be
365             // moved anymore.
366             return unsafe { Pin::new_unchecked(value) };
367         }
368
369         let slot = &self.value;
370
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(|_| {
374             let value = f();
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) });
382         });
383
384         // SAFETY: The inner value has been initialized, and will not be moved
385         // anymore.
386         unsafe { Pin::new_unchecked(self.get_ref().get_unchecked()) }
387     }
388
389     /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
390     /// `None` if the cell was empty.
391     ///
392     /// # Examples
393     ///
394     /// ```
395     /// #![feature(once_cell)]
396     ///
397     /// use std::lazy::SyncOnceCell;
398     ///
399     /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
400     /// assert_eq!(cell.into_inner(), None);
401     ///
402     /// let cell = SyncOnceCell::new();
403     /// cell.set("hello".to_string()).unwrap();
404     /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
405     /// ```
406     #[unstable(feature = "once_cell", issue = "74465")]
407     pub fn into_inner(mut self) -> Option<T> {
408         self.take()
409     }
410
411     /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
412     ///
413     /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
414     ///
415     /// Safety is guaranteed by requiring a mutable reference.
416     ///
417     /// # Examples
418     ///
419     /// ```
420     /// #![feature(once_cell)]
421     ///
422     /// use std::lazy::SyncOnceCell;
423     ///
424     /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
425     /// assert_eq!(cell.take(), None);
426     ///
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);
431     /// ```
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()) }
440         } else {
441             None
442         }
443     }
444
445     #[inline]
446     fn is_initialized(&self) -> bool {
447         self.once.is_completed()
448     }
449
450     #[cold]
451     fn initialize<F, E>(&self, f: F) -> Result<(), E>
452     where
453         F: FnOnce() -> Result<T, E>,
454     {
455         let mut res: Result<(), E> = Ok(());
456         let slot = &self.value;
457
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| {
461             match f() {
462                 Ok(value) => {
463                     unsafe { (&mut *slot.get()).write(value) };
464                 }
465                 Err(e) => {
466                     res = Err(e);
467
468                     // Treat the underlying `Once` as poisoned since we
469                     // failed to initialize our value. Calls
470                     p.poison();
471                 }
472             }
473         });
474         res
475     }
476
477     /// # Safety
478     ///
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()
483     }
484
485     /// # Safety
486     ///
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()
491     }
492 }
493
494 unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
495     fn drop(&mut self) {
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() };
501         }
502     }
503 }
504
505 /// A value which is initialized on the first access.
506 ///
507 /// This type is a thread-safe `Lazy`, and can be used in statics.
508 ///
509 /// # Examples
510 ///
511 /// ```
512 /// #![feature(once_cell)]
513 ///
514 /// use std::collections::HashMap;
515 ///
516 /// use std::lazy::SyncLazy;
517 ///
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());
523 ///     m
524 /// });
525 ///
526 /// fn main() {
527 ///     println!("ready");
528 ///     std::thread::spawn(|| {
529 ///         println!("{:?}", HASHMAP.get(&13));
530 ///     }).join().unwrap();
531 ///     println!("{:?}", HASHMAP.get(&74));
532 ///
533 ///     // Prints:
534 ///     //   ready
535 ///     //   initializing
536 ///     //   Some("Spica")
537 ///     //   Some("Hoyten")
538 /// }
539 /// ```
540 #[unstable(feature = "once_cell", issue = "74465")]
541 pub struct SyncLazy<T, F = fn() -> T> {
542     cell: SyncOnceCell<T>,
543     init: Cell<Option<F>>,
544 }
545
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()
550     }
551 }
552
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.
561
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 {}
566
567 impl<T, F> SyncLazy<T, F> {
568     /// Creates a new lazy value with the given initializing
569     /// function.
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)) }
573     }
574 }
575
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.
580     ///
581     /// # Examples
582     ///
583     /// ```
584     /// #![feature(once_cell)]
585     ///
586     /// use std::lazy::SyncLazy;
587     ///
588     /// let lazy = SyncLazy::new(|| 92);
589     ///
590     /// assert_eq!(SyncLazy::force(&lazy), &92);
591     /// assert_eq!(&*lazy, &92);
592     /// ```
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() {
596             Some(f) => f(),
597             None => panic!("Lazy instance has previously been poisoned"),
598         })
599     }
600 }
601
602 #[unstable(feature = "once_cell", issue = "74465")]
603 impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
604     type Target = T;
605     fn deref(&self) -> &T {
606         SyncLazy::force(self)
607     }
608 }
609
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)
615     }
616 }