about summary refs log tree commit diff
path: root/src/libcore/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-18 13:00:50 +0000
committerbors <bors@rust-lang.org>2020-07-18 13:00:50 +0000
commit7d31ffc1ac9e9ea356e896e63307168a64501b9d (patch)
treeaa1118412d2690e0e595788144b14970826c3d1f /src/libcore/tests
parentd3df8512d2c2afc6d2e7d8b5b951dd7f2ad77b02 (diff)
parentcae9c503b0d6de9702ca99bda95c081b1eb530f5 (diff)
Auto merge of #74468 - Manishearth:rollup-5nhvz80, r=Manishearth
Rollup of 11 pull requests

Successful merges:

 - #72414 ( Add lazy initialization primitives to std)
 - #74069 (Compare tagged/niche-filling layout and pick the best one)
 - #74418 (ci: Set `shell: bash` as a default, remove duplicates)
 - #74441 (bootstrap.py: patch RPATH on NixOS to handle the new zlib dependency.)
 - #74444 (Add regression test for #69414)
 - #74448 (improper_ctypes_definitions: allow `Box`)
 - #74449 (Test codegen of compare_exchange operations)
 - #74450 (Fix `Safety` docs for `from_raw_parts_mut`)
 - #74453 (Use intra-doc links in `str` and `BTreeSet`)
 - #74457 (rustbuild: drop tool::should_install)
 - #74464 (Use pathdiff crate)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libcore/tests')
-rw-r--r--src/libcore/tests/lazy.rs124
-rw-r--r--src/libcore/tests/lib.rs2
2 files changed, 126 insertions, 0 deletions
diff --git a/src/libcore/tests/lazy.rs b/src/libcore/tests/lazy.rs
new file mode 100644
index 00000000000..1c0bddb9aef
--- /dev/null
+++ b/src/libcore/tests/lazy.rs
@@ -0,0 +1,124 @@
+use core::{
+    cell::Cell,
+    lazy::{Lazy, OnceCell},
+    sync::atomic::{AtomicUsize, Ordering::SeqCst},
+};
+
+#[test]
+fn once_cell() {
+    let c = OnceCell::new();
+    assert!(c.get().is_none());
+    c.get_or_init(|| 92);
+    assert_eq!(c.get(), Some(&92));
+
+    c.get_or_init(|| panic!("Kabom!"));
+    assert_eq!(c.get(), Some(&92));
+}
+
+#[test]
+fn once_cell_get_mut() {
+    let mut c = OnceCell::new();
+    assert!(c.get_mut().is_none());
+    c.set(90).unwrap();
+    *c.get_mut().unwrap() += 2;
+    assert_eq!(c.get_mut(), Some(&mut 92));
+}
+
+#[test]
+fn once_cell_drop() {
+    static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
+    struct Dropper;
+    impl Drop for Dropper {
+        fn drop(&mut self) {
+            DROP_CNT.fetch_add(1, SeqCst);
+        }
+    }
+
+    let x = OnceCell::new();
+    x.get_or_init(|| Dropper);
+    assert_eq!(DROP_CNT.load(SeqCst), 0);
+    drop(x);
+    assert_eq!(DROP_CNT.load(SeqCst), 1);
+}
+
+#[test]
+fn unsync_once_cell_drop_empty() {
+    let x = OnceCell::<&'static str>::new();
+    drop(x);
+}
+
+#[test]
+fn clone() {
+    let s = OnceCell::new();
+    let c = s.clone();
+    assert!(c.get().is_none());
+
+    s.set("hello").unwrap();
+    let c = s.clone();
+    assert_eq!(c.get().map(|c| *c), Some("hello"));
+}
+
+#[test]
+fn from_impl() {
+    assert_eq!(OnceCell::from("value").get(), Some(&"value"));
+    assert_ne!(OnceCell::from("foo").get(), Some(&"bar"));
+}
+
+#[test]
+fn partialeq_impl() {
+    assert!(OnceCell::from("value") == OnceCell::from("value"));
+    assert!(OnceCell::from("foo") != OnceCell::from("bar"));
+
+    assert!(OnceCell::<&'static str>::new() == OnceCell::new());
+    assert!(OnceCell::<&'static str>::new() != OnceCell::from("value"));
+}
+
+#[test]
+fn into_inner() {
+    let cell: OnceCell<&'static str> = OnceCell::new();
+    assert_eq!(cell.into_inner(), None);
+    let cell = OnceCell::new();
+    cell.set("hello").unwrap();
+    assert_eq!(cell.into_inner(), Some("hello"));
+}
+
+#[test]
+fn lazy_new() {
+    let called = Cell::new(0);
+    let x = Lazy::new(|| {
+        called.set(called.get() + 1);
+        92
+    });
+
+    assert_eq!(called.get(), 0);
+
+    let y = *x - 30;
+    assert_eq!(y, 62);
+    assert_eq!(called.get(), 1);
+
+    let y = *x - 30;
+    assert_eq!(y, 62);
+    assert_eq!(called.get(), 1);
+}
+
+#[test]
+fn aliasing_in_get() {
+    let x = OnceCell::new();
+    x.set(42).unwrap();
+    let at_x = x.get().unwrap(); // --- (shared) borrow of inner `Option<T>` --+
+    let _ = x.set(27); // <-- temporary (unique) borrow of inner `Option<T>`   |
+    println!("{}", at_x); // <------- up until here ---------------------------+
+}
+
+#[test]
+#[should_panic(expected = "reentrant init")]
+fn reentrant_init() {
+    let x: OnceCell<Box<i32>> = OnceCell::new();
+    let dangling_ref: Cell<Option<&i32>> = Cell::new(None);
+    x.get_or_init(|| {
+        let r = x.get_or_init(|| Box::new(92));
+        dangling_ref.set(Some(r));
+        Box::new(62)
+    });
+    eprintln!("use after free: {:?}", dangling_ref.get().unwrap());
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 090ce471745..47ed6db6c67 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -43,6 +43,7 @@
 #![feature(option_unwrap_none)]
 #![feature(peekable_next_if)]
 #![feature(partition_point)]
+#![feature(once_cell)]
 #![feature(unsafe_block_in_unsafe_fn)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
@@ -62,6 +63,7 @@ mod fmt;
 mod hash;
 mod intrinsics;
 mod iter;
+mod lazy;
 mod manually_drop;
 mod mem;
 mod nonzero;