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