• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Original work Copyright (c) 2014 The Rust Project Developers
2 // Modified work Copyright (c) 2016-2020 Nikita Pekin and the lazycell contributors
3 // See the README.md file at the top-level directory of this distribution.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 #![cfg_attr(not(test), no_std)]
12 
13 #![deny(missing_docs)]
14 #![cfg_attr(feature = "nightly", feature(plugin))]
15 #![cfg_attr(feature = "clippy", plugin(clippy))]
16 
17 //! This crate provides a `LazyCell` struct which acts as a lazily filled
18 //! `Cell`.
19 //!
20 //! With a `RefCell`, the inner contents cannot be borrowed for the lifetime of
21 //! the entire object, but only of the borrows returned. A `LazyCell` is a
22 //! variation on `RefCell` which allows borrows to be tied to the lifetime of
23 //! the outer object.
24 //!
25 //! # Example
26 //!
27 //! The following example shows a quick example of the basic functionality of
28 //! `LazyCell`.
29 //!
30 //! ```
31 //! use lazycell::LazyCell;
32 //!
33 //! let lazycell = LazyCell::new();
34 //!
35 //! assert_eq!(lazycell.borrow(), None);
36 //! assert!(!lazycell.filled());
37 //! lazycell.fill(1).ok();
38 //! assert!(lazycell.filled());
39 //! assert_eq!(lazycell.borrow(), Some(&1));
40 //! assert_eq!(lazycell.into_inner(), Some(1));
41 //! ```
42 //!
43 //! `AtomicLazyCell` is a variant that uses an atomic variable to manage
44 //! coordination in a thread-safe fashion. The limitation of an `AtomicLazyCell`
45 //! is that after it is initialized, it can't be modified.
46 
47 
48 // ANDROID: Unconditionally use std to allow building as a dylib.
49 #[cfg(not(test))]
50 #[macro_use]
51 extern crate std;
52 #[cfg(feature = "serde")]
53 extern crate serde;
54 
55 #[cfg(feature = "serde")]
56 mod serde_impl;
57 
58 use std::cell::UnsafeCell;
59 use std::mem;
60 use std::sync::atomic::{AtomicUsize, Ordering};
61 
62 /// A lazily filled `Cell`, with mutable contents.
63 ///
64 /// A `LazyCell` is completely frozen once filled, **unless** you have `&mut`
65 /// access to it, in which case `LazyCell::borrow_mut` may be used to mutate the
66 /// contents.
67 #[derive(Debug)]
68 pub struct LazyCell<T> {
69     inner: UnsafeCell<Option<T>>,
70 }
71 
72 impl<T> LazyCell<T> {
73     /// Creates a new, empty, `LazyCell`.
new() -> LazyCell<T>74     pub fn new() -> LazyCell<T> {
75         LazyCell { inner: UnsafeCell::new(None) }
76     }
77 
78     /// Put a value into this cell.
79     ///
80     /// This function will return `Err(value)` if the cell is already full.
fill(&self, value: T) -> Result<(), T>81     pub fn fill(&self, value: T) -> Result<(), T> {
82         let slot = unsafe { &*self.inner.get() };
83         if slot.is_some() {
84             return Err(value);
85         }
86         let slot = unsafe { &mut *self.inner.get() };
87         *slot = Some(value);
88 
89         Ok(())
90     }
91 
92     /// Put a value into this cell.
93     ///
94     /// Note that this function is infallible but requires `&mut self`. By
95     /// requiring `&mut self` we're guaranteed that no active borrows to this
96     /// cell can exist so we can always fill in the value. This may not always
97     /// be usable, however, as `&mut self` may not be possible to borrow.
98     ///
99     /// # Return value
100     ///
101     /// This function returns the previous value, if any.
replace(&mut self, value: T) -> Option<T>102     pub fn replace(&mut self, value: T) -> Option<T> {
103         mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
104     }
105 
106     /// Test whether this cell has been previously filled.
filled(&self) -> bool107     pub fn filled(&self) -> bool {
108         self.borrow().is_some()
109     }
110 
111     /// Borrows the contents of this lazy cell for the duration of the cell
112     /// itself.
113     ///
114     /// This function will return `Some` if the cell has been previously
115     /// initialized, and `None` if it has not yet been initialized.
borrow(&self) -> Option<&T>116     pub fn borrow(&self) -> Option<&T> {
117         unsafe { &*self.inner.get() }.as_ref()
118     }
119 
120     /// Borrows the contents of this lazy cell mutably for the duration of the cell
121     /// itself.
122     ///
123     /// This function will return `Some` if the cell has been previously
124     /// initialized, and `None` if it has not yet been initialized.
borrow_mut(&mut self) -> Option<&mut T>125     pub fn borrow_mut(&mut self) -> Option<&mut T> {
126         unsafe { &mut *self.inner.get() }.as_mut()
127     }
128 
129     /// Borrows the contents of this lazy cell for the duration of the cell
130     /// itself.
131     ///
132     /// If the cell has not yet been filled, the cell is first filled using the
133     /// function provided.
134     ///
135     /// # Panics
136     ///
137     /// Panics if the cell becomes filled as a side effect of `f`.
borrow_with<F: FnOnce() -> T>(&self, f: F) -> &T138     pub fn borrow_with<F: FnOnce() -> T>(&self, f: F) -> &T {
139         if let Some(value) = self.borrow() {
140             return value;
141         }
142         let value = f();
143         if self.fill(value).is_err() {
144             panic!("borrow_with: cell was filled by closure")
145         }
146         self.borrow().unwrap()
147     }
148 
149     /// Borrows the contents of this `LazyCell` mutably for the duration of the
150     /// cell itself.
151     ///
152     /// If the cell has not yet been filled, the cell is first filled using the
153     /// function provided.
154     ///
155     /// # Panics
156     ///
157     /// Panics if the cell becomes filled as a side effect of `f`.
borrow_mut_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T158     pub fn borrow_mut_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
159         if !self.filled() {
160             let value = f();
161             if self.fill(value).is_err() {
162                 panic!("borrow_mut_with: cell was filled by closure")
163             }
164         }
165 
166         self.borrow_mut().unwrap()
167     }
168 
169     /// Same as `borrow_with`, but allows the initializing function to fail.
170     ///
171     /// # Panics
172     ///
173     /// Panics if the cell becomes filled as a side effect of `f`.
try_borrow_with<E, F>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E>174     pub fn try_borrow_with<E, F>(&self, f: F) -> Result<&T, E>
175         where F: FnOnce() -> Result<T, E>
176     {
177         if let Some(value) = self.borrow() {
178             return Ok(value);
179         }
180         let value = f()?;
181         if self.fill(value).is_err() {
182             panic!("try_borrow_with: cell was filled by closure")
183         }
184         Ok(self.borrow().unwrap())
185     }
186 
187     /// Same as `borrow_mut_with`, but allows the initializing function to fail.
188     ///
189     /// # Panics
190     ///
191     /// Panics if the cell becomes filled as a side effect of `f`.
try_borrow_mut_with<E, F>(&mut self, f: F) -> Result<&mut T, E> where F: FnOnce() -> Result<T, E>192     pub fn try_borrow_mut_with<E, F>(&mut self, f: F) -> Result<&mut T, E>
193         where F: FnOnce() -> Result<T, E>
194     {
195         if self.filled() {
196             return Ok(self.borrow_mut().unwrap());
197         }
198         let value = f()?;
199         if self.fill(value).is_err() {
200             panic!("try_borrow_mut_with: cell was filled by closure")
201         }
202         Ok(self.borrow_mut().unwrap())
203     }
204 
205     /// Consumes this `LazyCell`, returning the underlying value.
into_inner(self) -> Option<T>206     pub fn into_inner(self) -> Option<T> {
207         // Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
208         // function. This unsafe can be removed when supporting Rust older than
209         // 1.25 is not needed.
210         #[allow(unused_unsafe)]
211         unsafe { self.inner.into_inner() }
212     }
213 }
214 
215 impl<T: Copy> LazyCell<T> {
216     /// Returns a copy of the contents of the lazy cell.
217     ///
218     /// This function will return `Some` if the cell has been previously initialized,
219     /// and `None` if it has not yet been initialized.
get(&self) -> Option<T>220     pub fn get(&self) -> Option<T> {
221         unsafe { *self.inner.get() }
222     }
223 }
224 
225 impl<T> Default for LazyCell<T> {
default() -> Self226     fn default() -> Self {
227         Self::new()
228     }
229 }
230 
231 impl <T: Clone> Clone for LazyCell<T> {
232     /// Create a clone of this `LazyCell`
233     ///
234     /// If self has not been initialized, returns an uninitialized `LazyCell`
235     /// otherwise returns a `LazyCell` already initialized with a clone of the
236     /// contents of self.
clone(&self) -> LazyCell<T>237     fn clone(&self) -> LazyCell<T> {
238         LazyCell { inner: UnsafeCell::new(self.borrow().map(Clone::clone) ) }
239     }
240 }
241 
242 // Tracks the AtomicLazyCell inner state
243 const NONE: usize = 0;
244 const LOCK: usize = 1;
245 const SOME: usize = 2;
246 
247 /// A lazily filled and thread-safe `Cell`, with frozen contents.
248 #[derive(Debug)]
249 pub struct AtomicLazyCell<T> {
250     inner: UnsafeCell<Option<T>>,
251     state: AtomicUsize,
252 }
253 
254 impl<T> AtomicLazyCell<T> {
255     /// An empty `AtomicLazyCell`.
256     pub const NONE: Self = Self {
257         inner: UnsafeCell::new(None),
258         state: AtomicUsize::new(NONE),
259     };
260 
261     /// Creates a new, empty, `AtomicLazyCell`.
new() -> AtomicLazyCell<T>262     pub fn new() -> AtomicLazyCell<T> {
263         Self::NONE
264     }
265 
266     /// Put a value into this cell.
267     ///
268     /// This function will return `Err(value)` if the cell is already full.
fill(&self, t: T) -> Result<(), T>269     pub fn fill(&self, t: T) -> Result<(), T> {
270         if NONE != self.state.compare_and_swap(NONE, LOCK, Ordering::Acquire) {
271             return Err(t);
272         }
273 
274         unsafe { *self.inner.get() = Some(t) };
275 
276         if LOCK != self.state.compare_and_swap(LOCK, SOME, Ordering::Release) {
277             panic!("unable to release lock");
278         }
279 
280         Ok(())
281     }
282 
283     /// Put a value into this cell.
284     ///
285     /// Note that this function is infallible but requires `&mut self`. By
286     /// requiring `&mut self` we're guaranteed that no active borrows to this
287     /// cell can exist so we can always fill in the value. This may not always
288     /// be usable, however, as `&mut self` may not be possible to borrow.
289     ///
290     /// # Return value
291     ///
292     /// This function returns the previous value, if any.
replace(&mut self, value: T) -> Option<T>293     pub fn replace(&mut self, value: T) -> Option<T> {
294         match mem::replace(self.state.get_mut(), SOME) {
295             NONE | SOME => {}
296             _ => panic!("cell in inconsistent state"),
297         }
298         mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
299     }
300 
301     /// Test whether this cell has been previously filled.
filled(&self) -> bool302     pub fn filled(&self) -> bool {
303         self.state.load(Ordering::Acquire) == SOME
304     }
305 
306     /// Borrows the contents of this lazy cell for the duration of the cell
307     /// itself.
308     ///
309     /// This function will return `Some` if the cell has been previously
310     /// initialized, and `None` if it has not yet been initialized.
borrow(&self) -> Option<&T>311     pub fn borrow(&self) -> Option<&T> {
312         match self.state.load(Ordering::Acquire) {
313             SOME => unsafe { &*self.inner.get() }.as_ref(),
314             _ => None,
315         }
316     }
317 
318     /// Consumes this `LazyCell`, returning the underlying value.
into_inner(self) -> Option<T>319     pub fn into_inner(self) -> Option<T> {
320         // Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
321         // function. This unsafe can be removed when supporting Rust older than
322         // 1.25 is not needed.
323         #[allow(unused_unsafe)]
324         unsafe { self.inner.into_inner() }
325     }
326 }
327 
328 impl<T: Copy> AtomicLazyCell<T> {
329     /// Returns a copy of the contents of the lazy cell.
330     ///
331     /// This function will return `Some` if the cell has been previously initialized,
332     /// and `None` if it has not yet been initialized.
get(&self) -> Option<T>333     pub fn get(&self) -> Option<T> {
334         match self.state.load(Ordering::Acquire) {
335             SOME => unsafe { *self.inner.get() },
336             _ => None,
337         }
338     }
339 }
340 
341 impl<T> Default for AtomicLazyCell<T> {
default() -> Self342     fn default() -> Self {
343         Self::new()
344     }
345 }
346 
347 impl<T: Clone> Clone for AtomicLazyCell<T> {
348     /// Create a clone of this `AtomicLazyCell`
349     ///
350     /// If self has not been initialized, returns an uninitialized `AtomicLazyCell`
351     /// otherwise returns an `AtomicLazyCell` already initialized with a clone of the
352     /// contents of self.
clone(&self) -> AtomicLazyCell<T>353     fn clone(&self) -> AtomicLazyCell<T> {
354         self.borrow().map_or(
355             Self::NONE,
356             |v| AtomicLazyCell {
357                 inner: UnsafeCell::new(Some(v.clone())),
358                 state: AtomicUsize::new(SOME),
359             }
360         )
361     }
362 }
363 
364 unsafe impl<T: Sync + Send> Sync for AtomicLazyCell<T> {}
365 
366 unsafe impl<T: Send> Send for AtomicLazyCell<T> {}
367 
368 #[cfg(test)]
369 mod tests {
370     use super::{AtomicLazyCell, LazyCell};
371 
372     #[test]
test_borrow_from_empty()373     fn test_borrow_from_empty() {
374         let lazycell: LazyCell<usize> = LazyCell::new();
375 
376         let value = lazycell.borrow();
377         assert_eq!(value, None);
378 
379         let value = lazycell.get();
380         assert_eq!(value, None);
381     }
382 
383     #[test]
test_fill_and_borrow()384     fn test_fill_and_borrow() {
385         let lazycell = LazyCell::new();
386 
387         assert!(!lazycell.filled());
388         lazycell.fill(1).unwrap();
389         assert!(lazycell.filled());
390 
391         let value = lazycell.borrow();
392         assert_eq!(value, Some(&1));
393 
394         let value = lazycell.get();
395         assert_eq!(value, Some(1));
396     }
397 
398     #[test]
test_borrow_mut()399     fn test_borrow_mut() {
400         let mut lazycell = LazyCell::new();
401         assert!(lazycell.borrow_mut().is_none());
402 
403         lazycell.fill(1).unwrap();
404         assert_eq!(lazycell.borrow_mut(), Some(&mut 1));
405 
406         *lazycell.borrow_mut().unwrap() = 2;
407         assert_eq!(lazycell.borrow_mut(), Some(&mut 2));
408 
409         // official way to reset the cell
410         lazycell = LazyCell::new();
411         assert!(lazycell.borrow_mut().is_none());
412     }
413 
414     #[test]
test_already_filled_error()415     fn test_already_filled_error() {
416         let lazycell = LazyCell::new();
417 
418         lazycell.fill(1).unwrap();
419         assert_eq!(lazycell.fill(1), Err(1));
420     }
421 
422     #[test]
test_borrow_with()423     fn test_borrow_with() {
424         let lazycell = LazyCell::new();
425 
426         let value = lazycell.borrow_with(|| 1);
427         assert_eq!(&1, value);
428     }
429 
430     #[test]
test_borrow_with_already_filled()431     fn test_borrow_with_already_filled() {
432         let lazycell = LazyCell::new();
433         lazycell.fill(1).unwrap();
434 
435         let value = lazycell.borrow_with(|| 1);
436         assert_eq!(&1, value);
437     }
438 
439     #[test]
test_borrow_with_not_called_when_filled()440     fn test_borrow_with_not_called_when_filled() {
441         let lazycell = LazyCell::new();
442 
443         lazycell.fill(1).unwrap();
444 
445         let value = lazycell.borrow_with(|| 2);
446         assert_eq!(&1, value);
447     }
448 
449     #[test]
450     #[should_panic]
test_borrow_with_sound_with_reentrancy()451     fn test_borrow_with_sound_with_reentrancy() {
452         // Kudos to dbaupp for discovering this issue
453         // https://www.reddit.com/r/rust/comments/5vs9rt/lazycell_a_rust_library_providing_a_lazilyfilled/de527xm/
454         let lazycell: LazyCell<Box<i32>> = LazyCell::new();
455 
456         let mut reference: Option<&i32> = None;
457 
458         lazycell.borrow_with(|| {
459             let _ = lazycell.fill(Box::new(1));
460             reference = lazycell.borrow().map(|r| &**r);
461             Box::new(2)
462         });
463     }
464 
465     #[test]
test_borrow_mut_with()466     fn test_borrow_mut_with() {
467         let mut lazycell = LazyCell::new();
468 
469         {
470             let value = lazycell.borrow_mut_with(|| 1);
471             assert_eq!(&mut 1, value);
472             *value = 2;
473         }
474         assert_eq!(&2, lazycell.borrow().unwrap());
475     }
476 
477     #[test]
test_borrow_mut_with_already_filled()478     fn test_borrow_mut_with_already_filled() {
479         let mut lazycell = LazyCell::new();
480         lazycell.fill(1).unwrap();
481 
482         let value = lazycell.borrow_mut_with(|| 1);
483         assert_eq!(&1, value);
484     }
485 
486     #[test]
test_borrow_mut_with_not_called_when_filled()487     fn test_borrow_mut_with_not_called_when_filled() {
488         let mut lazycell = LazyCell::new();
489 
490         lazycell.fill(1).unwrap();
491 
492         let value = lazycell.borrow_mut_with(|| 2);
493         assert_eq!(&1, value);
494     }
495 
496     #[test]
test_try_borrow_with_ok()497     fn test_try_borrow_with_ok() {
498         let lazycell = LazyCell::new();
499         let result = lazycell.try_borrow_with::<(), _>(|| Ok(1));
500         assert_eq!(result, Ok(&1));
501     }
502 
503     #[test]
test_try_borrow_with_err()504     fn test_try_borrow_with_err() {
505         let lazycell = LazyCell::<()>::new();
506         let result = lazycell.try_borrow_with(|| Err(1));
507         assert_eq!(result, Err(1));
508     }
509 
510     #[test]
test_try_borrow_with_already_filled()511     fn test_try_borrow_with_already_filled() {
512         let lazycell = LazyCell::new();
513         lazycell.fill(1).unwrap();
514         let result = lazycell.try_borrow_with::<(), _>(|| unreachable!());
515         assert_eq!(result, Ok(&1));
516     }
517 
518     #[test]
519     #[should_panic]
test_try_borrow_with_sound_with_reentrancy()520     fn test_try_borrow_with_sound_with_reentrancy() {
521         let lazycell: LazyCell<Box<i32>> = LazyCell::new();
522 
523         let mut reference: Option<&i32> = None;
524 
525         let _ = lazycell.try_borrow_with::<(), _>(|| {
526             let _ = lazycell.fill(Box::new(1));
527             reference = lazycell.borrow().map(|r| &**r);
528             Ok(Box::new(2))
529         });
530     }
531 
532     #[test]
test_try_borrow_mut_with_ok()533     fn test_try_borrow_mut_with_ok() {
534         let mut lazycell = LazyCell::new();
535         {
536             let result = lazycell.try_borrow_mut_with::<(), _>(|| Ok(1));
537             assert_eq!(result, Ok(&mut 1));
538             *result.unwrap() = 2;
539         }
540         assert_eq!(&mut 2, lazycell.borrow().unwrap());
541     }
542 
543     #[test]
test_try_borrow_mut_with_err()544     fn test_try_borrow_mut_with_err() {
545         let mut lazycell = LazyCell::<()>::new();
546         let result = lazycell.try_borrow_mut_with(|| Err(1));
547         assert_eq!(result, Err(1));
548     }
549 
550     #[test]
test_try_borrow_mut_with_already_filled()551     fn test_try_borrow_mut_with_already_filled() {
552         let mut lazycell = LazyCell::new();
553         lazycell.fill(1).unwrap();
554         let result = lazycell.try_borrow_mut_with::<(), _>(|| unreachable!());
555         assert_eq!(result, Ok(&mut 1));
556     }
557 
558     #[test]
test_into_inner()559     fn test_into_inner() {
560         let lazycell = LazyCell::new();
561 
562         lazycell.fill(1).unwrap();
563         let value = lazycell.into_inner();
564         assert_eq!(value, Some(1));
565     }
566 
567     #[test]
test_atomic_borrow_from_empty()568     fn test_atomic_borrow_from_empty() {
569         let lazycell: AtomicLazyCell<usize> = AtomicLazyCell::new();
570 
571         let value = lazycell.borrow();
572         assert_eq!(value, None);
573 
574         let value = lazycell.get();
575         assert_eq!(value, None);
576     }
577 
578     #[test]
test_atomic_fill_and_borrow()579     fn test_atomic_fill_and_borrow() {
580         let lazycell = AtomicLazyCell::new();
581 
582         assert!(!lazycell.filled());
583         lazycell.fill(1).unwrap();
584         assert!(lazycell.filled());
585 
586         let value = lazycell.borrow();
587         assert_eq!(value, Some(&1));
588 
589         let value = lazycell.get();
590         assert_eq!(value, Some(1));
591     }
592 
593     #[test]
test_atomic_already_filled_panic()594     fn test_atomic_already_filled_panic() {
595         let lazycell = AtomicLazyCell::new();
596 
597         lazycell.fill(1).unwrap();
598         assert_eq!(1, lazycell.fill(1).unwrap_err());
599     }
600 
601     #[test]
test_atomic_into_inner()602     fn test_atomic_into_inner() {
603         let lazycell = AtomicLazyCell::new();
604 
605         lazycell.fill(1).unwrap();
606         let value = lazycell.into_inner();
607         assert_eq!(value, Some(1));
608     }
609 
610     #[test]
normal_replace()611     fn normal_replace() {
612         let mut cell = LazyCell::new();
613         assert_eq!(cell.fill(1), Ok(()));
614         assert_eq!(cell.replace(2), Some(1));
615         assert_eq!(cell.replace(3), Some(2));
616         assert_eq!(cell.borrow(), Some(&3));
617 
618         let mut cell = LazyCell::new();
619         assert_eq!(cell.replace(2), None);
620     }
621 
622     #[test]
atomic_replace()623     fn atomic_replace() {
624         let mut cell = AtomicLazyCell::new();
625         assert_eq!(cell.fill(1), Ok(()));
626         assert_eq!(cell.replace(2), Some(1));
627         assert_eq!(cell.replace(3), Some(2));
628         assert_eq!(cell.borrow(), Some(&3));
629     }
630 
631     #[test]
clone()632     fn clone() {
633         let mut cell = LazyCell::new();
634         let clone1 = cell.clone();
635         assert_eq!(clone1.borrow(), None);
636         assert_eq!(cell.fill(1), Ok(()));
637         let mut clone2 = cell.clone();
638         assert_eq!(clone1.borrow(), None);
639         assert_eq!(clone2.borrow(), Some(&1));
640         assert_eq!(cell.replace(2), Some(1));
641         assert_eq!(clone1.borrow(), None);
642         assert_eq!(clone2.borrow(), Some(&1));
643         assert_eq!(clone1.fill(3), Ok(()));
644         assert_eq!(clone2.replace(4), Some(1));
645         assert_eq!(clone1.borrow(), Some(&3));
646         assert_eq!(clone2.borrow(), Some(&4));
647         assert_eq!(cell.borrow(), Some(&2));
648     }
649 
650     #[test]
clone_atomic()651     fn clone_atomic() {
652         let mut cell = AtomicLazyCell::new();
653         let clone1 = cell.clone();
654         assert_eq!(clone1.borrow(), None);
655         assert_eq!(cell.fill(1), Ok(()));
656         let mut clone2 = cell.clone();
657         assert_eq!(clone1.borrow(), None);
658         assert_eq!(clone2.borrow(), Some(&1));
659         assert_eq!(cell.replace(2), Some(1));
660         assert_eq!(clone1.borrow(), None);
661         assert_eq!(clone2.borrow(), Some(&1));
662         assert_eq!(clone1.fill(3), Ok(()));
663         assert_eq!(clone2.replace(4), Some(1));
664         assert_eq!(clone1.borrow(), Some(&3));
665         assert_eq!(clone2.borrow(), Some(&4));
666         assert_eq!(cell.borrow(), Some(&2));
667     }
668 
669     #[test]
default()670     fn default() {
671         #[derive(Default)]
672         struct Defaultable;
673         struct NonDefaultable;
674 
675         let _: LazyCell<Defaultable> = LazyCell::default();
676         let _: LazyCell<NonDefaultable> = LazyCell::default();
677 
678         let _: AtomicLazyCell<Defaultable> = AtomicLazyCell::default();
679         let _: AtomicLazyCell<NonDefaultable> = AtomicLazyCell::default();
680     }
681 }
682