| // run-pass |
| |
| #![feature(untagged_unions)] |
| |
| #![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>>>()); |
| } |