about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2021-12-07 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2021-12-07 00:00:00 +0000
commit3cbe0f1b48dfdb7866f45a1d683b1391ed4d0508 (patch)
treeee60cd5aec17da1ed14751bae87700e5fadbddf7
parent0b6f079e4987ded15c13a15b734e7cfb8176839f (diff)
downloadrust-3cbe0f1b48dfdb7866f45a1d683b1391ed4d0508.tar.gz
rust-3cbe0f1b48dfdb7866f45a1d683b1391ed4d0508.zip
Add test for packed drops in generators
-rw-r--r--src/test/ui/packed/packed-struct-drop-aligned.rs28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/test/ui/packed/packed-struct-drop-aligned.rs b/src/test/ui/packed/packed-struct-drop-aligned.rs
index fab3bbedac6..b95cdbbbaad 100644
--- a/src/test/ui/packed/packed-struct-drop-aligned.rs
+++ b/src/test/ui/packed/packed-struct-drop-aligned.rs
@@ -1,6 +1,10 @@
 // run-pass
+#![feature(generators)]
+#![feature(generator_trait)]
 use std::cell::Cell;
 use std::mem;
+use std::ops::Generator;
+use std::pin::Pin;
 
 struct Aligned<'a> {
     drop_count: &'a Cell<usize>
@@ -19,15 +23,35 @@ impl<'a> Drop for Aligned<'a> {
     }
 }
 
+#[repr(transparent)]
+struct NotCopy(u8);
+
 #[repr(packed)]
-struct Packed<'a>(u8, Aligned<'a>);
+struct Packed<'a>(NotCopy, Aligned<'a>);
 
 fn main() {
     let drop_count = &Cell::new(0);
     {
-        let mut p = Packed(0, Aligned { drop_count });
+        let mut p = Packed(NotCopy(0), Aligned { drop_count });
         p.1 = Aligned { drop_count };
         assert_eq!(drop_count.get(), 1);
     }
     assert_eq!(drop_count.get(), 2);
+
+    let drop_count = &Cell::new(0);
+    let mut g = || {
+        let mut p = Packed(NotCopy(0), Aligned { drop_count });
+        let _ = &p;
+        p.1 = Aligned { drop_count };
+        assert_eq!(drop_count.get(), 1);
+        // Test that a generator drop function moves a value from a packed
+        // struct to a separate local before dropping it. We move out the
+        // first field to generate and open drop for the second field.
+        drop(p.0);
+        yield;
+    };
+    Pin::new(&mut g).resume(());
+    assert_eq!(drop_count.get(), 1);
+    drop(g);
+    assert_eq!(drop_count.get(), 2);
 }