1use crate::cell::UnsafeCell;
2use crate::fmt;
3use crate::marker::PhantomData;
4use crate::mem::MaybeUninit;
5use crate::panic::{RefUnwindSafe, UnwindSafe};
6use crate::sync::Once;
7
8/// A synchronization primitive which can be written to only once.
9///
10/// This type is a thread-safe [`OnceCell`], and can be used in statics.
11///
12/// [`OnceCell`]: crate::cell::OnceCell
13///
14/// # Examples
15///
16/// Using `OnceLock` to store a function’s previously computed value (a.k.a.
17/// ‘lazy static’ or ‘memoizing’):
18///
19/// ```
20/// use std::sync::OnceLock;
21///
22/// struct DeepThought {
23/// answer: String,
24/// }
25///
26/// impl DeepThought {
27/// # fn great_question() -> String {
28/// # "42".to_string()
29/// # }
30/// #
31/// fn new() -> Self {
32/// Self {
33/// // M3 Ultra takes about 16 million years in --release config
34/// answer: Self::great_question(),
35/// }
36/// }
37/// }
38///
39/// fn computation() -> &'static DeepThought {
40/// // n.b. static items do not call [`Drop`] on program termination, so if
41/// // [`DeepThought`] impls Drop, that will not be used for this instance.
42/// static COMPUTATION: OnceLock<DeepThought> = OnceLock::new();
43/// COMPUTATION.get_or_init(|| DeepThought::new())
44/// }
45///
46/// // The `DeepThought` is built, stored in the `OnceLock`, and returned.
47/// let _ = computation().answer;
48/// // The `DeepThought` is retrieved from the `OnceLock` and returned.
49/// let _ = computation().answer;
50/// ```
51///
52/// Writing to a `OnceLock` from a separate thread:
53///
54/// ```
55/// use std::sync::OnceLock;
56///
57/// static CELL: OnceLock<usize> = OnceLock::new();
58///
59/// // `OnceLock` has not been written to yet.
60/// assert!(CELL.get().is_none());
61///
62/// // Spawn a thread and write to `OnceLock`.
63/// std::thread::spawn(|| {
64/// let value = CELL.get_or_init(|| 12345);
65/// assert_eq!(value, &12345);
66/// })
67/// .join()
68/// .unwrap();
69///
70/// // `OnceLock` now contains the value.
71/// assert_eq!(
72/// CELL.get(),
73/// Some(&12345),
74/// );
75/// ```
76#[stable(feature = "once_cell", since = "1.70.0")]
77pub struct OnceLock<T> {
78 once: Once,
79 // Whether or not the value is initialized is tracked by `once.is_completed()`.
80 value: UnsafeCell<MaybeUninit<T>>,
81 /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
82 ///
83 /// ```compile_fail,E0597
84 /// use std::sync::OnceLock;
85 ///
86 /// struct A<'a>(&'a str);
87 ///
88 /// impl<'a> Drop for A<'a> {
89 /// fn drop(&mut self) {}
90 /// }
91 ///
92 /// let cell = OnceLock::new();
93 /// {
94 /// let s = String::new();
95 /// let _ = cell.set(A(&s));
96 /// }
97 /// ```
98 _marker: PhantomData<T>,
99}
100
101impl<T> OnceLock<T> {
102 /// Creates a new empty cell.
103 #[inline]
104 #[must_use]
105 #[stable(feature = "once_cell", since = "1.70.0")]
106 #[rustc_const_stable(feature = "once_cell", since = "1.70.0")]
107 pub const fn new() -> OnceLock<T> {
108 OnceLock {
109 once: Once::new(),
110 value: UnsafeCell::new(MaybeUninit::uninit()),
111 _marker: PhantomData,
112 }
113 }
114
115 /// Gets the reference to the underlying value.
116 ///
117 /// Returns `None` if the cell is empty, or being initialized. This
118 /// method never blocks.
119 #[inline]
120 #[stable(feature = "once_cell", since = "1.70.0")]
121 pub fn get(&self) -> Option<&T> {
122 if self.is_initialized() {
123 // Safe b/c checked is_initialized
124 Some(unsafe { self.get_unchecked() })
125 } else {
126 None
127 }
128 }
129
130 /// Gets the mutable reference to the underlying value.
131 ///
132 /// Returns `None` if the cell is empty. This method never blocks.
133 #[inline]
134 #[stable(feature = "once_cell", since = "1.70.0")]
135 pub fn get_mut(&mut self) -> Option<&mut T> {
136 if self.is_initialized() {
137 // Safe b/c checked is_initialized and we have a unique access
138 Some(unsafe { self.get_unchecked_mut() })
139 } else {
140 None
141 }
142 }
143
144 /// Sets the contents of this cell to `value`.
145 ///
146 /// May block if another thread is currently attempting to initialize the cell. The cell is
147 /// guaranteed to contain a value when set returns, though not necessarily the one provided.
148 ///
149 /// Returns `Ok(())` if the cell's value was set by this call.
150 ///
151 /// # Examples
152 ///
153 /// ```
154 /// use std::sync::OnceLock;
155 ///
156 /// static CELL: OnceLock<i32> = OnceLock::new();
157 ///
158 /// fn main() {
159 /// assert!(CELL.get().is_none());
160 ///
161 /// std::thread::spawn(|| {
162 /// assert_eq!(CELL.set(92), Ok(()));
163 /// }).join().unwrap();
164 ///
165 /// assert_eq!(CELL.set(62), Err(62));
166 /// assert_eq!(CELL.get(), Some(&92));
167 /// }
168 /// ```
169 #[inline]
170 #[stable(feature = "once_cell", since = "1.70.0")]
171 pub fn set(&self, value: T) -> Result<(), T> {
172 match self.try_insert(value) {
173 Ok(_) => Ok(()),
174 Err((_, value)) => Err(value),
175 }
176 }
177
178 /// Sets the contents of this cell to `value` if the cell was empty, then
179 /// returns a reference to it.
180 ///
181 /// May block if another thread is currently attempting to initialize the cell. The cell is
182 /// guaranteed to contain a value when set returns, though not necessarily the one provided.
183 ///
184 /// Returns `Ok(&value)` if the cell was empty and `Err(&current_value, value)` if it was full.
185 ///
186 /// # Examples
187 ///
188 /// ```
189 /// #![feature(once_cell_try_insert)]
190 ///
191 /// use std::sync::OnceLock;
192 ///
193 /// static CELL: OnceLock<i32> = OnceLock::new();
194 ///
195 /// fn main() {
196 /// assert!(CELL.get().is_none());
197 ///
198 /// std::thread::spawn(|| {
199 /// assert_eq!(CELL.try_insert(92), Ok(&92));
200 /// }).join().unwrap();
201 ///
202 /// assert_eq!(CELL.try_insert(62), Err((&92, 62)));
203 /// assert_eq!(CELL.get(), Some(&92));
204 /// }
205 /// ```
206 #[inline]
207 #[unstable(feature = "once_cell_try_insert", issue = "116693")]
208 pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
209 let mut value = Some(value);
210 let res = self.get_or_init(|| value.take().unwrap());
211 match value {
212 None => Ok(res),
213 Some(value) => Err((res, value)),
214 }
215 }
216
217 /// Gets the contents of the cell, initializing it with `f` if the cell
218 /// was empty.
219 ///
220 /// Many threads may call `get_or_init` concurrently with different
221 /// initializing functions, but it is guaranteed that only one function
222 /// will be executed.
223 ///
224 /// # Panics
225 ///
226 /// If `f` panics, the panic is propagated to the caller, and the cell
227 /// remains uninitialized.
228 ///
229 /// It is an error to reentrantly initialize the cell from `f`. The
230 /// exact outcome is unspecified. Current implementation deadlocks, but
231 /// this may be changed to a panic in the future.
232 ///
233 /// # Examples
234 ///
235 /// ```
236 /// use std::sync::OnceLock;
237 ///
238 /// let cell = OnceLock::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 #[inline]
245 #[stable(feature = "once_cell", since = "1.70.0")]
246 pub fn get_or_init<F>(&self, f: F) -> &T
247 where
248 F: FnOnce() -> T,
249 {
250 match self.get_or_try_init(|| Ok::<T, !>(f())) {
251 Ok(val) => val,
252 }
253 }
254
255 /// Gets the mutable reference of the contents of the cell, initializing
256 /// it with `f` if the cell was empty.
257 ///
258 /// Many threads may call `get_mut_or_init` concurrently with different
259 /// initializing functions, but it is guaranteed that only one function
260 /// will be executed.
261 ///
262 /// # Panics
263 ///
264 /// If `f` panics, the panic is propagated to the caller, and the cell
265 /// remains uninitialized.
266 ///
267 /// # Examples
268 ///
269 /// ```
270 /// #![feature(once_cell_get_mut)]
271 ///
272 /// use std::sync::OnceLock;
273 ///
274 /// let mut cell = OnceLock::new();
275 /// let value = cell.get_mut_or_init(|| 92);
276 /// assert_eq!(*value, 92);
277 ///
278 /// *value += 2;
279 /// assert_eq!(*value, 94);
280 ///
281 /// let value = cell.get_mut_or_init(|| unreachable!());
282 /// assert_eq!(*value, 94);
283 /// ```
284 #[inline]
285 #[unstable(feature = "once_cell_get_mut", issue = "121641")]
286 pub fn get_mut_or_init<F>(&mut self, f: F) -> &mut T
287 where
288 F: FnOnce() -> T,
289 {
290 match self.get_mut_or_try_init(|| Ok::<T, !>(f())) {
291 Ok(val) => val,
292 }
293 }
294
295 /// Gets the contents of the cell, initializing it with `f` if
296 /// the cell was empty. If the cell was empty and `f` failed, an
297 /// error is returned.
298 ///
299 /// # Panics
300 ///
301 /// If `f` panics, the panic is propagated to the caller, and
302 /// the cell remains uninitialized.
303 ///
304 /// It is an error to reentrantly initialize the cell from `f`.
305 /// The exact outcome is unspecified. Current implementation
306 /// deadlocks, but this may be changed to a panic in the future.
307 ///
308 /// # Examples
309 ///
310 /// ```
311 /// #![feature(once_cell_try)]
312 ///
313 /// use std::sync::OnceLock;
314 ///
315 /// let cell = OnceLock::new();
316 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
317 /// assert!(cell.get().is_none());
318 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
319 /// Ok(92)
320 /// });
321 /// assert_eq!(value, Ok(&92));
322 /// assert_eq!(cell.get(), Some(&92))
323 /// ```
324 #[inline]
325 #[unstable(feature = "once_cell_try", issue = "109737")]
326 pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
327 where
328 F: FnOnce() -> Result<T, E>,
329 {
330 // Fast path check
331 // NOTE: We need to perform an acquire on the state in this method
332 // in order to correctly synchronize `LazyLock::force`. This is
333 // currently done by calling `self.get()`, which in turn calls
334 // `self.is_initialized()`, which in turn performs the acquire.
335 if let Some(value) = self.get() {
336 return Ok(value);
337 }
338 self.initialize(f)?;
339
340 debug_assert!(self.is_initialized());
341
342 // SAFETY: The inner value has been initialized
343 Ok(unsafe { self.get_unchecked() })
344 }
345
346 /// Gets the mutable reference of the contents of the cell, initializing
347 /// it with `f` if the cell was empty. If the cell was empty and `f` failed,
348 /// an error is returned.
349 ///
350 /// # Panics
351 ///
352 /// If `f` panics, the panic is propagated to the caller, and
353 /// the cell remains uninitialized.
354 ///
355 /// # Examples
356 ///
357 /// ```
358 /// #![feature(once_cell_get_mut)]
359 ///
360 /// use std::sync::OnceLock;
361 ///
362 /// let mut cell: OnceLock<u32> = OnceLock::new();
363 ///
364 /// // Failed initializers do not change the value
365 /// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
366 /// assert!(cell.get().is_none());
367 ///
368 /// let value = cell.get_mut_or_try_init(|| "1234".parse());
369 /// assert_eq!(value, Ok(&mut 1234));
370 /// *value.unwrap() += 2;
371 /// assert_eq!(cell.get(), Some(&1236))
372 /// ```
373 #[inline]
374 #[unstable(feature = "once_cell_get_mut", issue = "121641")]
375 pub fn get_mut_or_try_init<F, E>(&mut self, f: F) -> Result<&mut T, E>
376 where
377 F: FnOnce() -> Result<T, E>,
378 {
379 if self.get().is_none() {
380 self.initialize(f)?;
381 }
382 debug_assert!(self.is_initialized());
383 // SAFETY: The inner value has been initialized
384 Ok(unsafe { self.get_unchecked_mut() })
385 }
386
387 /// Consumes the `OnceLock`, returning the wrapped value. Returns
388 /// `None` if the cell was empty.
389 ///
390 /// # Examples
391 ///
392 /// ```
393 /// use std::sync::OnceLock;
394 ///
395 /// let cell: OnceLock<String> = OnceLock::new();
396 /// assert_eq!(cell.into_inner(), None);
397 ///
398 /// let cell = OnceLock::new();
399 /// cell.set("hello".to_string()).unwrap();
400 /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
401 /// ```
402 #[inline]
403 #[stable(feature = "once_cell", since = "1.70.0")]
404 pub fn into_inner(mut self) -> Option<T> {
405 self.take()
406 }
407
408 /// Takes the value out of this `OnceLock`, moving it back to an uninitialized state.
409 ///
410 /// Has no effect and returns `None` if the `OnceLock` hasn't been initialized.
411 ///
412 /// Safety is guaranteed by requiring a mutable reference.
413 ///
414 /// # Examples
415 ///
416 /// ```
417 /// use std::sync::OnceLock;
418 ///
419 /// let mut cell: OnceLock<String> = OnceLock::new();
420 /// assert_eq!(cell.take(), None);
421 ///
422 /// let mut cell = OnceLock::new();
423 /// cell.set("hello".to_string()).unwrap();
424 /// assert_eq!(cell.take(), Some("hello".to_string()));
425 /// assert_eq!(cell.get(), None);
426 /// ```
427 #[inline]
428 #[stable(feature = "once_cell", since = "1.70.0")]
429 pub fn take(&mut self) -> Option<T> {
430 if self.is_initialized() {
431 self.once = Once::new();
432 // SAFETY: `self.value` is initialized and contains a valid `T`.
433 // `self.once` is reset, so `is_initialized()` will be false again
434 // which prevents the value from being read twice.
435 unsafe { Some((&mut *self.value.get()).assume_init_read()) }
436 } else {
437 None
438 }
439 }
440
441 #[inline]
442 fn is_initialized(&self) -> bool {
443 self.once.is_completed()
444 }
445
446 #[cold]
447 fn initialize<F, E>(&self, f: F) -> Result<(), E>
448 where
449 F: FnOnce() -> Result<T, E>,
450 {
451 let mut res: Result<(), E> = Ok(());
452 let slot = &self.value;
453
454 // Ignore poisoning from other threads
455 // If another thread panics, then we'll be able to run our closure
456 self.once.call_once_force(|p| {
457 match f() {
458 Ok(value) => {
459 unsafe { (&mut *slot.get()).write(value) };
460 }
461 Err(e) => {
462 res = Err(e);
463
464 // Treat the underlying `Once` as poisoned since we
465 // failed to initialize our value. Calls
466 p.poison();
467 }
468 }
469 });
470 res
471 }
472
473 /// # Safety
474 ///
475 /// The value must be initialized
476 #[inline]
477 unsafe fn get_unchecked(&self) -> &T {
478 debug_assert!(self.is_initialized());
479 (&*self.value.get()).assume_init_ref()
480 }
481
482 /// # Safety
483 ///
484 /// The value must be initialized
485 #[inline]
486 unsafe fn get_unchecked_mut(&mut self) -> &mut T {
487 debug_assert!(self.is_initialized());
488 (&mut *self.value.get()).assume_init_mut()
489 }
490}
491
492// Why do we need `T: Send`?
493// Thread A creates a `OnceLock` and shares it with
494// scoped thread B, which fills the cell, which is
495// then destroyed by A. That is, destructor observes
496// a sent value.
497#[stable(feature = "once_cell", since = "1.70.0")]
498unsafe impl<T: Sync + Send> Sync for OnceLock<T> {}
499#[stable(feature = "once_cell", since = "1.70.0")]
500unsafe impl<T: Send> Send for OnceLock<T> {}
501
502#[stable(feature = "once_cell", since = "1.70.0")]
503impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {}
504#[stable(feature = "once_cell", since = "1.70.0")]
505impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}
506
507#[stable(feature = "once_cell", since = "1.70.0")]
508impl<T> Default for OnceLock<T> {
509 /// Creates a new empty cell.
510 ///
511 /// # Example
512 ///
513 /// ```
514 /// use std::sync::OnceLock;
515 ///
516 /// fn main() {
517 /// assert_eq!(OnceLock::<()>::new(), OnceLock::default());
518 /// }
519 /// ```
520 #[inline]
521 fn default() -> OnceLock<T> {
522 OnceLock::new()
523 }
524}
525
526#[stable(feature = "once_cell", since = "1.70.0")]
527impl<T: fmt::Debug> fmt::Debug for OnceLock<T> {
528 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
529 let mut d: DebugTuple<'_, '_> = f.debug_tuple(name:"OnceLock");
530 match self.get() {
531 Some(v: &T) => d.field(v),
532 None => d.field(&format_args!("<uninit>")),
533 };
534 d.finish()
535 }
536}
537
538#[stable(feature = "once_cell", since = "1.70.0")]
539impl<T: Clone> Clone for OnceLock<T> {
540 #[inline]
541 fn clone(&self) -> OnceLock<T> {
542 let cell: OnceLock = Self::new();
543 if let Some(value: &T) = self.get() {
544 match cell.set(value.clone()) {
545 Ok(()) => (),
546 Err(_) => unreachable!(),
547 }
548 }
549 cell
550 }
551}
552
553#[stable(feature = "once_cell", since = "1.70.0")]
554impl<T> From<T> for OnceLock<T> {
555 /// Create a new cell with its contents set to `value`.
556 ///
557 /// # Example
558 ///
559 /// ```
560 /// use std::sync::OnceLock;
561 ///
562 /// # fn main() -> Result<(), i32> {
563 /// let a = OnceLock::from(3);
564 /// let b = OnceLock::new();
565 /// b.set(3)?;
566 /// assert_eq!(a, b);
567 /// Ok(())
568 /// # }
569 /// ```
570 #[inline]
571 fn from(value: T) -> Self {
572 let cell = Self::new();
573 match cell.set(value) {
574 Ok(()) => cell,
575 Err(_) => unreachable!(),
576 }
577 }
578}
579
580#[stable(feature = "once_cell", since = "1.70.0")]
581impl<T: PartialEq> PartialEq for OnceLock<T> {
582 #[inline]
583 fn eq(&self, other: &OnceLock<T>) -> bool {
584 self.get() == other.get()
585 }
586}
587
588#[stable(feature = "once_cell", since = "1.70.0")]
589impl<T: Eq> Eq for OnceLock<T> {}
590
591#[stable(feature = "once_cell", since = "1.70.0")]
592unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
593 #[inline]
594 fn drop(&mut self) {
595 if self.is_initialized() {
596 // SAFETY: The cell is initialized and being dropped, so it can't
597 // be accessed again. We also don't touch the `T` other than
598 // dropping it, which validates our usage of #[may_dangle].
599 unsafe { (&mut *self.value.get()).assume_init_drop() };
600 }
601 }
602}
603
604#[cfg(test)]
605mod tests;
606