]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #75648 - matklad:lazy-dropck, r=KodrAus
authorTyler Mandry <tmandry@gmail.com>
Wed, 19 Aug 2020 18:12:20 +0000 (11:12 -0700)
committerGitHub <noreply@github.com>
Wed, 19 Aug 2020 18:12:20 +0000 (11:12 -0700)
Make OnceCell<T> transparent to dropck

See the failed build in

https://github.com/rust-lang/rust/pull/75555#issuecomment-675016718

for an example where we need this in real life

r? @ghost

library/core/tests/lazy.rs
library/std/src/lazy.rs

index 1c0bddb9aef624c4671ae98aa201f4ed10c02dae..24f921ca7e4dc7a277d30c737577197cb8f72d06 100644 (file)
@@ -122,3 +122,12 @@ fn reentrant_init() {
     });
     eprintln!("use after free: {:?}", dangling_ref.get().unwrap());
 }
+
+#[test]
+fn dropck() {
+    let cell = OnceCell::new();
+    {
+        let s = String::new();
+        cell.set(&s).unwrap();
+    }
+}
index 60eba96bcc0156f8f0357ce1dbb25fc304d5e95d..c1d05213e1147d6640bb59710f2d86944124b191 100644 (file)
@@ -386,9 +386,10 @@ unsafe fn get_unchecked_mut(&mut self) -> &mut T {
     }
 }
 
-impl<T> Drop for SyncOnceCell<T> {
+unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
     fn drop(&mut self) {
-        // Safety: The cell is being dropped, so it can't be accessed again
+        // Safety: The cell is being dropped, so it can't be accessed again.
+        // We also don't touch the `T`, which validates our usage of #[may_dangle].
         unsafe { self.take_inner() };
     }
 }
@@ -845,4 +846,13 @@ fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
             assert_eq!(msg, MSG);
         }
     }
+
+    #[test]
+    fn dropck() {
+        let cell = SyncOnceCell::new();
+        {
+            let s = String::new();
+            cell.set(&s).unwrap();
+        }
+    }
 }