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