tracing_core/lazy.rs
1#[cfg(feature = "std")]
2pub(crate) use once_cell::sync::Lazy;
3
4#[cfg(not(feature = "std"))]
5pub(crate) use self::spin::Lazy;
6
7// FIXME(https://fxbug.dev/42082971): We can unfork tracing-core once it no longer vendors the `spin`
8// crate.
9#[cfg(not(feature = "std"))]
10mod spin {
11 std::compile_error!("The fuchsia fork of tracing-core requires the `std` feature");
12}
13
14/*
15#[cfg(not(feature = "std"))]
16mod spin {
17 //! This is the `once_cell::sync::Lazy` type, but modified to use our
18 //! `spin::Once` type rather than `OnceCell`. This is used to replace
19 //! `once_cell::sync::Lazy` on `no-std` builds.
20 use crate::spin::Once;
21 use core::{cell::Cell, fmt, ops::Deref};
22
23 /// Re-implementation of `once_cell::sync::Lazy` on top of `spin::Once`
24 /// rather than `OnceCell`.
25 ///
26 /// This is used when the standard library is disabled.
27 pub(crate) struct Lazy<T, F = fn() -> T> {
28 cell: Once<T>,
29 init: Cell<Option<F>>,
30 }
31
32 impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 f.debug_struct("Lazy")
35 .field("cell", &self.cell)
36 .field("init", &"..")
37 .finish()
38 }
39 }
40
41 // We never create a `&F` from a `&Lazy<T, F>` so it is fine to not impl
42 // `Sync` for `F`. We do create a `&mut Option<F>` in `force`, but this is
43 // properly synchronized, so it only happens once so it also does not
44 // contribute to this impl.
45 unsafe impl<T, F: Send> Sync for Lazy<T, F> where Once<T>: Sync {}
46 // auto-derived `Send` impl is OK.
47
48 impl<T, F> Lazy<T, F> {
49 /// Creates a new lazy value with the given initializing function.
50 pub(crate) const fn new(init: F) -> Lazy<T, F> {
51 Lazy {
52 cell: Once::new(),
53 init: Cell::new(Some(init)),
54 }
55 }
56 }
57
58 impl<T, F: FnOnce() -> T> Lazy<T, F> {
59 /// Forces the evaluation of this lazy value and returns a reference to
60 /// the result.
61 ///
62 /// This is equivalent to the `Deref` impl, but is explicit.
63 pub(crate) fn force(this: &Lazy<T, F>) -> &T {
64 this.cell.call_once(|| match this.init.take() {
65 Some(f) => f(),
66 None => panic!("Lazy instance has previously been poisoned"),
67 })
68 }
69 }
70
71 impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
72 type Target = T;
73 fn deref(&self) -> &T {
74 Lazy::force(self)
75 }
76 }
77
78 impl<T: Default> Default for Lazy<T> {
79 /// Creates a new lazy value using `Default` as the initializing function.
80 fn default() -> Lazy<T> {
81 Lazy::new(T::default)
82 }
83 }
84}
85*/