1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
use crate::cell::UnsafeCell;
use crate::mem::ManuallyDrop;
use crate::ops::Deref;
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::sync::Once;
use crate::{fmt, ptr};

use super::once::ExclusiveState;

// 我们使用 Once 的状态作为判别值。
// 创建时,状态为 "incomplete",`f` 包含初始化闭包。
// 在第一次调用 `call_once` 时,`f` 被取走运行。
// 如果成功,则设置 `value` 并将状态更改为 "complete"。
// 如果出现 panic,则 Once 中毒,因此这两个字段均未初始化。
union Data<T, F> {
    value: ManuallyDrop<T>,
    f: ManuallyDrop<F>,
}

/// 在首次访问时初始化的值。
///
/// 此类型是线程安全的 [`LazyCell`],可用于静态。
///
/// [`LazyCell`]: crate::cell::LazyCell
///
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::collections::HashMap;
///
/// use std::sync::LazyLock;
///
/// static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| {
///     println!("initializing");
///     let mut m = HashMap::new();
///     m.insert(13, "Spica".to_string());
///     m.insert(74, "Hoyten".to_string());
///     m
/// });
///
/// fn main() {
///     println!("ready");
///     std::thread::spawn(|| {
///         println!("{:?}", HASHMAP.get(&13));
///     }).join().unwrap();
///     println!("{:?}", HASHMAP.get(&74));
///
///     // Prints:
///     //   准备初始化
/////
///     //   Some("Spica")
///     //   Some("Hoyten")
/// }
/// ```
#[unstable(feature = "lazy_cell", issue = "109736")]
pub struct LazyLock<T, F = fn() -> T> {
    once: Once,
    data: UnsafeCell<Data<T, F>>,
}

impl<T, F: FnOnce() -> T> LazyLock<T, F> {
    /// 使用给定的初始化函数创建一个新的惰性值。
    ///
    #[inline]
    #[unstable(feature = "lazy_cell", issue = "109736")]
    pub const fn new(f: F) -> LazyLock<T, F> {
        LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
    }

    /// 使用此 `LazyLock` 返回存储的值。
    ///
    /// 如果 `Lazy` 已初始化,则返回 `Ok(value)`,否则返回 `Err(f)`。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(lazy_cell)]
    /// #![feature(lazy_cell_consume)]
    ///
    /// use std::sync::LazyLock;
    ///
    /// let hello = "Hello, World!".to_string();
    ///
    /// let lazy = LazyLock::new(|| hello.to_uppercase());
    ///
    /// assert_eq!(&*lazy, "HELLO, WORLD!");
    /// assert_eq!(LazyLock::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
    /// ```
    #[unstable(feature = "lazy_cell_consume", issue = "109736")]
    pub fn into_inner(mut this: Self) -> Result<T, F> {
        let state = this.once.state();
        match state {
            ExclusiveState::Poisoned => panic!("LazyLock instance has previously been poisoned"),
            state => {
                let this = ManuallyDrop::new(this);
                let data = unsafe { ptr::read(&this.data) }.into_inner();
                match state {
                    ExclusiveState::Incomplete => Err(ManuallyDrop::into_inner(unsafe { data.f })),
                    ExclusiveState::Complete => Ok(ManuallyDrop::into_inner(unsafe { data.value })),
                    ExclusiveState::Poisoned => unreachable!(),
                }
            }
        }
    }

    /// 强制评估此惰性值,并返回引数以得出结果。
    /// 这等效于 `Deref` impl,但是是显式的。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(lazy_cell)]
    ///
    /// use std::sync::LazyLock;
    ///
    /// let lazy = LazyLock::new(|| 92);
    ///
    /// assert_eq!(LazyLock::force(&lazy), &92);
    /// assert_eq!(&*lazy, &92);
    /// ```
    ///
    #[inline]
    #[unstable(feature = "lazy_cell", issue = "109736")]
    pub fn force(this: &LazyLock<T, F>) -> &T {
        this.once.call_once(|| {
            // SAFETY: `call_once` 只运行一次这个闭包,永远。
            let data = unsafe { &mut *this.data.get() };
            let f = unsafe { ManuallyDrop::take(&mut data.f) };
            let value = f();
            data.value = ManuallyDrop::new(value);
        });

        // SAFETY:
        // 有四种可能的情况:
        // * 闭包被调用并初始化了 `value`。
        // * 闭包被叫着慌了,所以一直到不了这个地步。
        // * 闭包没有被调用,而是之前的一个调用初始化了 `value`。
        // * 封包没叫是因为 Once 中毒了,所以一直没到这个地步。
        //
        // 所以 `value` 肯定已经初始化过了,不会再修改了。
        unsafe { &*(*this.data.get()).value }
    }
}

impl<T, F> LazyLock<T, F> {
    /// 如果已经初始化,则获取内部值。
    fn get(&self) -> Option<&T> {
        if self.once.is_completed() {
            // SAFETY:
            // 闭包已经运行成功,所以 `value` 已经初始化,不再修改。
            //
            Some(unsafe { &*(*self.data.get()).value })
        } else {
            None
        }
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T, F> Drop for LazyLock<T, F> {
    fn drop(&mut self) {
        match self.once.state() {
            ExclusiveState::Incomplete => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().f) },
            ExclusiveState::Complete => unsafe {
                ManuallyDrop::drop(&mut self.data.get_mut().value)
            },
            ExclusiveState::Poisoned => {}
        }
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        LazyLock::force(self)
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T: Default> Default for LazyLock<T> {
    /// 使用 `Default` 作为初始化函数创建一个新的惰性值。
    #[inline]
    fn default() -> LazyLock<T> {
        LazyLock::new(T::default)
    }
}

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.get() {
            Some(v) => f.debug_tuple("LazyLock").field(v).finish(),
            None => f.write_str("LazyLock(Uninit)"),
        }
    }
}

// 我们从不从 `&LazyLock<T, F>` 创建 `&F`,所以不为 `F` 实现 `Sync` 是可以的
//
#[unstable(feature = "lazy_cell", issue = "109736")]
unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
// 自动派生的 `Send` impl 是可以的。

#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
#[unstable(feature = "lazy_cell", issue = "109736")]
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}

#[cfg(test)]
mod tests;