]> git.lizzy.rs Git - rust.git/commitdiff
Make unions never have needs_drop
authorManish Goregaokar <manishsmail@gmail.com>
Mon, 9 Jan 2017 15:13:28 +0000 (07:13 -0800)
committerManish Goregaokar <manishsmail@gmail.com>
Mon, 9 Jan 2017 18:44:41 +0000 (10:44 -0800)
src/librustc/ty/contents.rs
src/test/run-pass/union/union-nodrop.rs [new file with mode: 0644]

index 8c3cb7929488064cb3982949452d352e121388bd..ed5b470849c41f4ef948c095443cee2ba0e974f2 100644 (file)
@@ -235,6 +235,11 @@ fn tc_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             })
                         });
 
+                    if def.is_union() {
+                        // unions don't have destructors regardless of the child types
+                        res = res - TC::NeedsDrop;
+                    }
+
                     if def.has_dtor() {
                         res = res | TC::OwnsDtor;
                     }
diff --git a/src/test/run-pass/union/union-nodrop.rs b/src/test/run-pass/union/union-nodrop.rs
new file mode 100644 (file)
index 0000000..22f00be
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(core_intrinsics)]
+#![feature(untagged_unions)]
+
+#![allow(unions_with_drop_fields)]
+#![allow(dead_code)]
+
+use std::intrinsics::needs_drop;
+
+// drop types in destructors should not require
+// drop_types_in_const
+static X: Option<NoDrop<Box<u8>>> = None;
+
+// A union that scrubs the drop glue from its inner type
+union NoDrop<T> {inner: 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: T}
+
+impl<T> Drop for ActuallyDrop<T> {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    unsafe {
+        // 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>>>());
+    }
+}