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*/