summaryrefslogtreecommitdiffstats
path: root/tests/ui/union/union-nodrop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/union/union-nodrop.rs')
-rw-r--r--tests/ui/union/union-nodrop.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/tests/ui/union/union-nodrop.rs b/tests/ui/union/union-nodrop.rs
new file mode 100644
index 000000000..6e6b105a7
--- /dev/null
+++ b/tests/ui/union/union-nodrop.rs
@@ -0,0 +1,62 @@
+// run-pass
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![allow(dead_code)]
+
+use std::mem::needs_drop;
+use std::mem::ManuallyDrop;
+
+struct NeedDrop;
+
+impl Drop for NeedDrop {
+ fn drop(&mut self) {}
+}
+
+// Constant expressios allow `NoDrop` to go out of scope,
+// unlike a value of the interior type implementing `Drop`.
+static X: () = (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1;
+
+const Y: () = (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1;
+
+const fn _f() { (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1 }
+
+// A union that scrubs the drop glue from its inner type
+union NoDrop<T> { inner: ManuallyDrop<T> }
+
+// Copy currently can't be implemented on drop-containing unions,
+// this may change later
+// https://github.com/rust-lang/rust/pull/38934#issuecomment-271219289
+
+// // We should be able to implement Copy for NoDrop
+// impl<T> Copy for NoDrop<T> {}
+// impl<T> Clone for NoDrop<T> {fn clone(&self) -> Self { *self }}
+
+// // We should be able to implement Copy for things using NoDrop
+// #[derive(Copy, Clone)]
+struct Foo {
+ x: NoDrop<Box<u8>>
+}
+
+struct Baz {
+ x: NoDrop<Box<u8>>,
+ y: Box<u8>,
+}
+
+union ActuallyDrop<T> { inner: ManuallyDrop<T> }
+
+impl<T> Drop for ActuallyDrop<T> {
+ fn drop(&mut self) {}
+}
+
+fn main() {
+ // NoDrop should not make needs_drop true
+ assert!(!needs_drop::<Foo>());
+ assert!(!needs_drop::<NoDrop<u8>>());
+ assert!(!needs_drop::<NoDrop<Box<u8>>>());
+ // presence of other drop types should still work
+ assert!(needs_drop::<Baz>());
+ // drop impl on union itself should work
+ assert!(needs_drop::<ActuallyDrop<u8>>());
+ assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
+}