about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/attr-usage-repr.rs2
-rw-r--r--src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs44
-rw-r--r--src/test/compile-fail/borrowck/borrowck-union-borrow.rs97
-rw-r--r--src/test/compile-fail/borrowck/borrowck-union-move-assign.rs42
-rw-r--r--src/test/compile-fail/borrowck/borrowck-union-move.rs96
-rw-r--r--src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs30
-rw-r--r--src/test/compile-fail/deriving-non-type.rs18
-rw-r--r--src/test/compile-fail/issue-17800.rs2
-rw-r--r--src/test/compile-fail/issue-19922.rs2
-rw-r--r--src/test/compile-fail/issue-31769.rs2
-rw-r--r--src/test/compile-fail/issue-4736.rs2
-rw-r--r--src/test/compile-fail/numeric-fields.rs2
-rw-r--r--src/test/compile-fail/privacy/union-field-privacy-1.rs30
-rw-r--r--src/test/compile-fail/privacy/union-field-privacy-2.rs28
-rw-r--r--src/test/compile-fail/struct-fields-hints-no-dupe.rs2
-rw-r--r--src/test/compile-fail/struct-fields-hints.rs2
-rw-r--r--src/test/compile-fail/struct-fields-too-many.rs2
-rw-r--r--src/test/compile-fail/suggest-private-fields.rs8
-rw-r--r--src/test/compile-fail/union/union-const-eval.rs26
-rw-r--r--src/test/compile-fail/union/union-const-pat.rs25
-rw-r--r--src/test/compile-fail/union/union-copy.rs26
-rw-r--r--src/test/compile-fail/union/union-derive.rs30
-rw-r--r--src/test/compile-fail/union/union-empty.rs15
-rw-r--r--src/test/compile-fail/union/union-feature-gate.rs15
-rw-r--r--src/test/compile-fail/union/union-fields.rs35
-rw-r--r--src/test/compile-fail/union/union-generic.rs24
-rw-r--r--src/test/compile-fail/union/union-nonrepresentable.rs18
-rw-r--r--src/test/compile-fail/union/union-repr-c.rs29
-rw-r--r--src/test/compile-fail/union/union-suggest-field.rs29
-rw-r--r--src/test/compile-fail/union/union-unsafe.rs24
-rw-r--r--src/test/compile-fail/union/union-unsized.rs23
-rw-r--r--src/test/compile-fail/union/union-with-drop-fields-lint.rs40
-rw-r--r--src/test/debuginfo/union-smoke.rs50
-rw-r--r--src/test/incremental/struct_change_field_name.rs2
-rw-r--r--src/test/run-pass/union/auxiliary/union.rs16
-rw-r--r--src/test/run-pass/union/union-backcomp.rs27
-rw-r--r--src/test/run-pass/union/union-basic.rs68
-rw-r--r--src/test/run-pass/union/union-c-interop.rs47
-rw-r--r--src/test/run-pass/union/union-const-trans.rs27
-rw-r--r--src/test/run-pass/union/union-derive.rs31
-rw-r--r--src/test/run-pass/union/union-drop-assign.rs44
-rw-r--r--src/test/run-pass/union/union-drop.rs65
-rw-r--r--src/test/run-pass/union/union-generic.rs43
-rw-r--r--src/test/run-pass/union/union-inherent-method.rs24
-rw-r--r--src/test/run-pass/union/union-macro.rs33
-rw-r--r--src/test/run-pass/union/union-overwrite.rs80
-rw-r--r--src/test/run-pass/union/union-packed.rs104
-rw-r--r--src/test/run-pass/union/union-pat-refutability.rs62
-rw-r--r--src/test/run-pass/union/union-trait-impl.rs27
-rw-r--r--src/test/run-pass/union/union-transmute.rs40
-rw-r--r--src/test/run-pass/union/union-with-drop-fields-lint.rs42
-rw-r--r--src/test/rustdoc/union.rs20
52 files changed, 1599 insertions, 23 deletions
diff --git a/src/test/compile-fail/attr-usage-repr.rs b/src/test/compile-fail/attr-usage-repr.rs
index 9bad6a8389a..b07d3e2f906 100644
--- a/src/test/compile-fail/attr-usage-repr.rs
+++ b/src/test/compile-fail/attr-usage-repr.rs
@@ -11,7 +11,7 @@
 #![allow(dead_code)]
 #![feature(repr_simd)]
 
-#[repr(C)] //~ ERROR: attribute should be applied to struct or enum
+#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
 fn f() {}
 
 #[repr(C)]
diff --git a/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs b/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs
new file mode 100644
index 00000000000..19975d79b60
--- /dev/null
+++ b/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs
@@ -0,0 +1,44 @@
+// 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.
+
+// ignore-tidy-linelength
+
+#![feature(untagged_unions)]
+
+#[derive(Clone, Copy)]
+struct S {
+    a: u8,
+    b: u16,
+}
+
+union U {
+    s: S,
+    c: u32,
+}
+
+impl Clone for U {
+    fn clone(&self) -> Self { *self }
+}
+impl Copy for U {}
+
+fn main() {
+    unsafe {
+        {
+            let mut u = U { s: S { a: 0, b: 1 } };
+            let ra = &mut u.s.a;
+            let b = u.s.b; // OK
+        }
+        {
+            let mut u = U { s: S { a: 0, b: 1 } };
+            let ra = &mut u.s.a;
+            let b = u.c; //~ ERROR cannot use `u.c` because it was mutably borrowed
+        }
+    }
+}
diff --git a/src/test/compile-fail/borrowck/borrowck-union-borrow.rs b/src/test/compile-fail/borrowck/borrowck-union-borrow.rs
new file mode 100644
index 00000000000..e8989a3c2d4
--- /dev/null
+++ b/src/test/compile-fail/borrowck/borrowck-union-borrow.rs
@@ -0,0 +1,97 @@
+// 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.
+
+// ignore-tidy-linelength
+
+#![feature(untagged_unions)]
+
+union U {
+    a: u8,
+    b: u64,
+}
+
+impl Clone for U {
+    fn clone(&self) -> Self { *self }
+}
+impl Copy for U {}
+
+fn main() {
+    unsafe {
+        let mut u = U { b: 0 };
+        // Imm borrow, same field
+        {
+            let ra = &u.a;
+            let ra2 = &u.a; // OK
+        }
+        {
+            let ra = &u.a;
+            let a = u.a; // OK
+        }
+        {
+            let ra = &u.a;
+            let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
+        }
+        {
+            let ra = &u.a;
+            u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
+        }
+        // Imm borrow, other field
+        {
+            let ra = &u.a;
+            let rb = &u.b; // OK
+        }
+        {
+            let ra = &u.a;
+            let b = u.b; // OK
+        }
+        {
+            let ra = &u.a;
+            let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
+        }
+        {
+            let ra = &u.a;
+            u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
+        }
+        // Mut borrow, same field
+        {
+            let rma = &mut u.a;
+            let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
+        }
+        {
+            let ra = &mut u.a;
+            let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
+        }
+        {
+            let rma = &mut u.a;
+            let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
+        }
+        {
+            let rma = &mut u.a;
+            u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
+        }
+        // Mut borrow, other field
+        {
+            let rma = &mut u.a;
+            let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
+        }
+        {
+            let ra = &mut u.a;
+            let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
+        }
+        {
+            let rma = &mut u.a;
+            let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
+        }
+        {
+            let rma = &mut u.a;
+            u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
+        }
+    }
+}
diff --git a/src/test/compile-fail/borrowck/borrowck-union-move-assign.rs b/src/test/compile-fail/borrowck/borrowck-union-move-assign.rs
new file mode 100644
index 00000000000..d4d7bc6b0f7
--- /dev/null
+++ b/src/test/compile-fail/borrowck/borrowck-union-move-assign.rs
@@ -0,0 +1,42 @@
+// 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(untagged_unions)]
+
+// Non-copy
+struct A;
+struct B;
+
+union U {
+    a: A,
+    b: B,
+}
+
+fn main() {
+    unsafe {
+        {
+            let mut u = U { a: A };
+            let a = u.a;
+            let a = u.a; //~ ERROR use of moved value: `u.a`
+        }
+        {
+            let mut u = U { a: A };
+            let a = u.a;
+            u.a = A;
+            let a = u.a; // OK
+        }
+        {
+            let mut u = U { a: A };
+            let a = u.a;
+            u.b = B;
+            let a = u.a; // OK
+        }
+    }
+}
diff --git a/src/test/compile-fail/borrowck/borrowck-union-move.rs b/src/test/compile-fail/borrowck/borrowck-union-move.rs
new file mode 100644
index 00000000000..5320244cf43
--- /dev/null
+++ b/src/test/compile-fail/borrowck/borrowck-union-move.rs
@@ -0,0 +1,96 @@
+// 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(untagged_unions)]
+
+#[derive(Clone, Copy)]
+struct Copy;
+struct NonCopy;
+
+union Unn {
+    n1: NonCopy,
+    n2: NonCopy,
+}
+union Ucc {
+    c1: Copy,
+    c2: Copy,
+}
+union Ucn {
+    c: Copy,
+    n: NonCopy,
+}
+
+fn main() {
+    unsafe {
+        // 2 NonCopy
+        {
+            let mut u = Unn { n1: NonCopy };
+            let a = u.n1;
+            let a = u.n1; //~ ERROR use of moved value: `u.n1`
+        }
+        {
+            let mut u = Unn { n1: NonCopy };
+            let a = u.n1;
+            let a = u; //~ ERROR use of partially moved value: `u`
+        }
+        {
+            let mut u = Unn { n1: NonCopy };
+            let a = u.n1;
+            let a = u.n2; //~ ERROR use of moved value: `u.n2`
+        }
+        // 2 Copy
+        {
+            let mut u = Ucc { c1: Copy };
+            let a = u.c1;
+            let a = u.c1; // OK
+        }
+        {
+            let mut u = Ucc { c1: Copy };
+            let a = u.c1;
+            let a = u; // OK
+        }
+        {
+            let mut u = Ucc { c1: Copy };
+            let a = u.c1;
+            let a = u.c2; // OK
+        }
+        // 1 Copy, 1 NonCopy
+        {
+            let mut u = Ucn { c: Copy };
+            let a = u.c;
+            let a = u.c; // OK
+        }
+        {
+            let mut u = Ucn { c: Copy };
+            let a = u.n;
+            let a = u.n; //~ ERROR use of moved value: `u.n`
+        }
+        {
+            let mut u = Ucn { c: Copy };
+            let a = u.n;
+            let a = u.c; //~ ERROR use of moved value: `u.c`
+        }
+        {
+            let mut u = Ucn { c: Copy };
+            let a = u.c;
+            let a = u.n; // OK
+        }
+        {
+            let mut u = Ucn { c: Copy };
+            let a = u.c;
+            let a = u; // OK
+        }
+        {
+            let mut u = Ucn { c: Copy };
+            let a = u.n;
+            let a = u; //~ ERROR use of partially moved value: `u`
+        }
+    }
+}
diff --git a/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs b/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs
new file mode 100644
index 00000000000..36e062f8464
--- /dev/null
+++ b/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs
@@ -0,0 +1,30 @@
+// 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(untagged_unions)]
+
+struct S {
+    a: u8,
+}
+
+union U {
+    a: u8,
+}
+
+fn main() {
+    unsafe {
+        let mut s: S;
+        let mut u: U;
+        s.a = 0;
+        u.a = 0;
+        let sa = s.a; //~ ERROR use of possibly uninitialized variable: `s.a`
+        let ua = u.a; //~ ERROR use of possibly uninitialized variable: `u.a`
+    }
+}
diff --git a/src/test/compile-fail/deriving-non-type.rs b/src/test/compile-fail/deriving-non-type.rs
index 5b215f3ccd9..84dd22435b8 100644
--- a/src/test/compile-fail/deriving-non-type.rs
+++ b/src/test/compile-fail/deriving-non-type.rs
@@ -12,29 +12,29 @@
 
 struct S;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 trait T { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 impl S { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 impl T for S { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 static s: usize = 0;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 const c: usize = 0;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 mod m { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 extern "C" { }
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 type A = usize;
 
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
 fn main() { }
diff --git a/src/test/compile-fail/issue-17800.rs b/src/test/compile-fail/issue-17800.rs
index 58d580a5c1a..d5f1614c14d 100644
--- a/src/test/compile-fail/issue-17800.rs
+++ b/src/test/compile-fail/issue-17800.rs
@@ -18,7 +18,7 @@ enum MyOption<T> {
 fn main() {
     match MyOption::MySome(42) {
         MyOption::MySome { x: 42 } => (),
-        //~^ ERROR struct `MyOption::MySome` does not have a field named `x`
+        //~^ ERROR variant `MyOption::MySome` does not have a field named `x`
         //~| ERROR pattern does not mention field `0`
         _ => (),
     }
diff --git a/src/test/compile-fail/issue-19922.rs b/src/test/compile-fail/issue-19922.rs
index e3ced302809..a8350fe0986 100644
--- a/src/test/compile-fail/issue-19922.rs
+++ b/src/test/compile-fail/issue-19922.rs
@@ -14,5 +14,5 @@ enum Homura {
 
 fn main() {
     let homura = Homura::Akemi { kaname: () };
-    //~^ ERROR struct variant `Homura::Akemi` has no field named `kaname`
+    //~^ ERROR variant `Homura::Akemi` has no field named `kaname`
 }
diff --git a/src/test/compile-fail/issue-31769.rs b/src/test/compile-fail/issue-31769.rs
index 4b5df7ea53c..7f73d9076ec 100644
--- a/src/test/compile-fail/issue-31769.rs
+++ b/src/test/compile-fail/issue-31769.rs
@@ -10,5 +10,5 @@
 
 fn main() {
     #[inline] struct Foo;  //~ ERROR attribute should be applied to function
-    #[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct or enum
+    #[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum or union
 }
diff --git a/src/test/compile-fail/issue-4736.rs b/src/test/compile-fail/issue-4736.rs
index a8a1b1482fc..c93e75042dd 100644
--- a/src/test/compile-fail/issue-4736.rs
+++ b/src/test/compile-fail/issue-4736.rs
@@ -13,5 +13,5 @@
 struct NonCopyable(());
 
 fn main() {
-    let z = NonCopyable{ p: () }; //~ ERROR structure `NonCopyable` has no field named `p`
+    let z = NonCopyable{ p: () }; //~ ERROR struct `NonCopyable` has no field named `p`
 }
diff --git a/src/test/compile-fail/numeric-fields.rs b/src/test/compile-fail/numeric-fields.rs
index 480d2dcdddd..c4aff9471b8 100644
--- a/src/test/compile-fail/numeric-fields.rs
+++ b/src/test/compile-fail/numeric-fields.rs
@@ -13,7 +13,7 @@
 struct S(u8, u16);
 
 fn main() {
-    let s = S{0b1: 10, 0: 11}; //~ ERROR structure `S` has no field named `0b1`
+    let s = S{0b1: 10, 0: 11}; //~ ERROR struct `S` has no field named `0b1`
     match s {
         S{0: a, 0x1: b, ..} => {} //~ ERROR does not have a field named `0x1`
     }
diff --git a/src/test/compile-fail/privacy/union-field-privacy-1.rs b/src/test/compile-fail/privacy/union-field-privacy-1.rs
new file mode 100644
index 00000000000..4924fabafb0
--- /dev/null
+++ b/src/test/compile-fail/privacy/union-field-privacy-1.rs
@@ -0,0 +1,30 @@
+// 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(pub_restricted)]
+#![feature(untagged_unions)]
+
+mod m {
+    pub union U {
+        pub a: u8,
+        pub(super) b: u8,
+        c: u8,
+    }
+}
+
+fn main() {
+    let u = m::U { a: 0 }; // OK
+    let u = m::U { b: 0 }; // OK
+    let u = m::U { c: 0 }; //~ ERROR field `c` of union `m::U` is private
+
+    let m::U { a } = u; // OK
+    let m::U { b } = u; // OK
+    let m::U { c } = u; //~ ERROR field `c` of union `m::U` is private
+}
diff --git a/src/test/compile-fail/privacy/union-field-privacy-2.rs b/src/test/compile-fail/privacy/union-field-privacy-2.rs
new file mode 100644
index 00000000000..7151538f412
--- /dev/null
+++ b/src/test/compile-fail/privacy/union-field-privacy-2.rs
@@ -0,0 +1,28 @@
+// 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(pub_restricted)]
+#![feature(untagged_unions)]
+
+mod m {
+    pub union U {
+        pub a: u8,
+        pub(super) b: u8,
+        c: u8,
+    }
+}
+
+fn main() {
+    let u = m::U { a: 10 };
+
+    let a = u.a; // OK
+    let b = u.b; // OK
+    let c = u.c; //~ ERROR field `c` of struct `m::U` is private
+}
diff --git a/src/test/compile-fail/struct-fields-hints-no-dupe.rs b/src/test/compile-fail/struct-fields-hints-no-dupe.rs
index 8df9ffd6cc7..5f1f8ca856f 100644
--- a/src/test/compile-fail/struct-fields-hints-no-dupe.rs
+++ b/src/test/compile-fail/struct-fields-hints-no-dupe.rs
@@ -17,7 +17,7 @@ struct A {
 fn main() {
     let a = A {
         foo : 5,
-        bar : 42,//~ ERROR structure `A` has no field named `bar`
+        bar : 42,//~ ERROR struct `A` has no field named `bar`
         //~^ HELP did you mean `barr`?
         car : 9,
     };
diff --git a/src/test/compile-fail/struct-fields-hints.rs b/src/test/compile-fail/struct-fields-hints.rs
index 37001f1e60a..4ba1fd2f7bb 100644
--- a/src/test/compile-fail/struct-fields-hints.rs
+++ b/src/test/compile-fail/struct-fields-hints.rs
@@ -17,7 +17,7 @@ struct A {
 fn main() {
     let a = A {
         foo : 5,
-        bar : 42,//~ ERROR structure `A` has no field named `bar`
+        bar : 42,//~ ERROR struct `A` has no field named `bar`
         //~^ HELP did you mean `car`?
     };
 }
diff --git a/src/test/compile-fail/struct-fields-too-many.rs b/src/test/compile-fail/struct-fields-too-many.rs
index 9244a9d4f9d..5d16573f2f1 100644
--- a/src/test/compile-fail/struct-fields-too-many.rs
+++ b/src/test/compile-fail/struct-fields-too-many.rs
@@ -15,6 +15,6 @@ struct BuildData {
 fn main() {
     let foo = BuildData {
         foo: 0,
-        bar: 0 //~ ERROR structure `BuildData` has no field named `bar`
+        bar: 0 //~ ERROR struct `BuildData` has no field named `bar`
     };
 }
diff --git a/src/test/compile-fail/suggest-private-fields.rs b/src/test/compile-fail/suggest-private-fields.rs
index 9c61f618e69..41bd00a518c 100644
--- a/src/test/compile-fail/suggest-private-fields.rs
+++ b/src/test/compile-fail/suggest-private-fields.rs
@@ -22,16 +22,16 @@ struct A {
 fn main () {
     // external crate struct
     let k = B {
-        aa: 20, //~ ERROR structure `xc::B` has no field named `aa`
+        aa: 20, //~ ERROR struct `xc::B` has no field named `aa`
         //~^ HELP did you mean `a`?
-        bb: 20, //~ ERROR structure `xc::B` has no field named `bb`
+        bb: 20, //~ ERROR struct `xc::B` has no field named `bb`
         //~^ HELP did you mean `a`?
     };
     // local crate struct
     let l = A {
-        aa: 20, //~ ERROR structure `A` has no field named `aa`
+        aa: 20, //~ ERROR struct `A` has no field named `aa`
         //~^ HELP did you mean `a`?
-        bb: 20, //~ ERROR structure `A` has no field named `bb`
+        bb: 20, //~ ERROR struct `A` has no field named `bb`
         //~^ HELP did you mean `b`?
     };
 }
diff --git a/src/test/compile-fail/union/union-const-eval.rs b/src/test/compile-fail/union/union-const-eval.rs
new file mode 100644
index 00000000000..b2bf173c59c
--- /dev/null
+++ b/src/test/compile-fail/union/union-const-eval.rs
@@ -0,0 +1,26 @@
+// 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(untagged_unions)]
+
+union U {
+    a: usize,
+    b: usize,
+}
+
+const C: U = U { a: 10 };
+
+fn main() {
+    unsafe {
+        let a: [u8; C.a]; // OK
+        let b: [u8; C.b]; //~ ERROR constant evaluation error
+                          //~^ NOTE nonexistent struct field
+    }
+}
diff --git a/src/test/compile-fail/union/union-const-pat.rs b/src/test/compile-fail/union/union-const-pat.rs
new file mode 100644
index 00000000000..3d168980ed2
--- /dev/null
+++ b/src/test/compile-fail/union/union-const-pat.rs
@@ -0,0 +1,25 @@
+// 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(untagged_unions)]
+
+union U {
+    a: usize,
+    b: usize,
+}
+
+const C: U = U { a: 10 };
+
+fn main() {
+    match C {
+        C => {} //~ ERROR cannot use unions in constant patterns
+        _ => {}
+    }
+}
diff --git a/src/test/compile-fail/union/union-copy.rs b/src/test/compile-fail/union/union-copy.rs
new file mode 100644
index 00000000000..6e08ae0074d
--- /dev/null
+++ b/src/test/compile-fail/union/union-copy.rs
@@ -0,0 +1,26 @@
+// 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(untagged_unions)]
+
+union U {
+    a: u8
+}
+
+union W {
+    a: String
+}
+
+impl Clone for U { fn clone(&self) { panic!(); } }
+impl Clone for W { fn clone(&self) { panic!(); } }
+impl Copy for U {} // OK
+impl Copy for W {} //~ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-derive.rs b/src/test/compile-fail/union/union-derive.rs
new file mode 100644
index 00000000000..0f78e96f640
--- /dev/null
+++ b/src/test/compile-fail/union/union-derive.rs
@@ -0,0 +1,30 @@
+// 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.
+
+// Most traits cannot be derived for unions.
+
+#![feature(untagged_unions)]
+
+#[derive(
+    Clone, //~ ERROR this trait cannot be derived for unions
+    PartialEq, //~ ERROR this trait cannot be derived for unions
+    Eq, //~ ERROR this trait cannot be derived for unions
+    PartialOrd, //~ ERROR this trait cannot be derived for unions
+    Ord, //~ ERROR this trait cannot be derived for unions
+    Hash, //~ ERROR this trait cannot be derived for unions
+    Default, //~ ERROR this trait cannot be derived for unions
+    Debug, //~ ERROR this trait cannot be derived for unions
+)]
+union U {
+    a: u8,
+    b: u16,
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-empty.rs b/src/test/compile-fail/union/union-empty.rs
new file mode 100644
index 00000000000..ce5bbf60fee
--- /dev/null
+++ b/src/test/compile-fail/union/union-empty.rs
@@ -0,0 +1,15 @@
+// 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(untagged_unions)]
+
+union U {} //~ ERROR unions cannot have zero fields
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-feature-gate.rs b/src/test/compile-fail/union/union-feature-gate.rs
new file mode 100644
index 00000000000..abfc4d90921
--- /dev/null
+++ b/src/test/compile-fail/union/union-feature-gate.rs
@@ -0,0 +1,15 @@
+// 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.
+
+union U { //~ ERROR unions are unstable and possibly buggy
+    a: u8,
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-fields.rs b/src/test/compile-fail/union/union-fields.rs
new file mode 100644
index 00000000000..a1721dda7de
--- /dev/null
+++ b/src/test/compile-fail/union/union-fields.rs
@@ -0,0 +1,35 @@
+// 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(untagged_unions)]
+
+union U {
+    a: u8,
+    b: u16,
+}
+
+fn main() {
+    let u = U {}; //~ ERROR union expressions should have exactly one field
+    let u = U { a: 0 }; // OK
+    let u = U { a: 0, b: 1 }; //~ ERROR union expressions should have exactly one field
+    let u = U { a: 0, b: 1, c: 2 }; //~ ERROR union expressions should have exactly one field
+                                    //~^ ERROR union `U` has no field named `c`
+    let u = U { ..u }; //~ ERROR union expressions should have exactly one field
+                       //~^ ERROR functional record update syntax requires a struct
+
+    let U {} = u; //~ ERROR union patterns should have exactly one field
+    let U { a } = u; // OK
+    let U { a, b } = u; //~ ERROR union patterns should have exactly one field
+    let U { a, b, c } = u; //~ ERROR union patterns should have exactly one field
+                           //~^ ERROR union `U` does not have a field named `c`
+    let U { .. } = u; //~ ERROR union patterns should have exactly one field
+                      //~^ ERROR `..` cannot be used in union patterns
+    let U { a, .. } = u; //~ ERROR `..` cannot be used in union patterns
+}
diff --git a/src/test/compile-fail/union/union-generic.rs b/src/test/compile-fail/union/union-generic.rs
new file mode 100644
index 00000000000..e6586b0fb7f
--- /dev/null
+++ b/src/test/compile-fail/union/union-generic.rs
@@ -0,0 +1,24 @@
+// 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(untagged_unions)]
+
+use std::rc::Rc;
+
+union U<T: Copy> {
+    a: T
+}
+
+fn main() {
+    let u = U { a: Rc::new(0u32) };
+    //~^ ERROR  the trait bound `std::rc::Rc<u32>: std::marker::Copy` is not satisfied
+    let u = U::<Rc<u32>> { a: Default::default() };
+    //~^ ERROR  the trait bound `std::rc::Rc<u32>: std::marker::Copy` is not satisfied
+}
diff --git a/src/test/compile-fail/union/union-nonrepresentable.rs b/src/test/compile-fail/union/union-nonrepresentable.rs
new file mode 100644
index 00000000000..cb4683c2a0e
--- /dev/null
+++ b/src/test/compile-fail/union/union-nonrepresentable.rs
@@ -0,0 +1,18 @@
+// 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(untagged_unions)]
+
+union U { //~ ERROR recursive type `U` has infinite size
+    a: u8,
+    b: U,
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-repr-c.rs b/src/test/compile-fail/union/union-repr-c.rs
new file mode 100644
index 00000000000..d7dfb126c93
--- /dev/null
+++ b/src/test/compile-fail/union/union-repr-c.rs
@@ -0,0 +1,29 @@
+// 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(untagged_unions)]
+#![allow(unused)]
+#![deny(improper_ctypes)]
+
+#[repr(C)]
+union U {
+    a: u8,
+}
+
+union W {
+    a: u8,
+}
+
+extern "C" {
+    static FOREIGN1: U; // OK
+    static FOREIGN2: W; //~ ERROR found union without foreign-function-safe representation
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-suggest-field.rs b/src/test/compile-fail/union/union-suggest-field.rs
new file mode 100644
index 00000000000..b05e9b6e273
--- /dev/null
+++ b/src/test/compile-fail/union/union-suggest-field.rs
@@ -0,0 +1,29 @@
+// 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(untagged_unions)]
+
+union U {
+    principal: u8,
+}
+
+impl U {
+    fn calculate(&self) {}
+}
+
+fn main() {
+    let u = U { principle: 0 }; //~ ERROR union `U` has no field named `principle`
+                                //~^ HELP did you mean `principal`?
+    let w = u.principial; //~ ERROR attempted access of field `principial` on type `U`
+                          //~^ HELP did you mean `principal`?
+
+    let y = u.calculate; //~ ERROR attempted to take value of method `calculate` on type `U`
+                         //~^ HELP maybe a `()` to call it is missing?
+}
diff --git a/src/test/compile-fail/union/union-unsafe.rs b/src/test/compile-fail/union/union-unsafe.rs
new file mode 100644
index 00000000000..97e1ec2cba8
--- /dev/null
+++ b/src/test/compile-fail/union/union-unsafe.rs
@@ -0,0 +1,24 @@
+// 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(untagged_unions)]
+
+union U {
+    a: u8
+}
+
+fn main() {
+    let mut u = U { a: 10 }; // OK
+    let a = u.a; //~ ERROR access to union field requires unsafe function or block
+    u.a = 11; //~ ERROR access to union field requires unsafe function or block
+    let U { a } = u; //~ ERROR matching on union field requires unsafe function or block
+    if let U { a: 12 } = u {} //~ ERROR matching on union field requires unsafe function or block
+    // let U { .. } = u; // OK
+}
diff --git a/src/test/compile-fail/union/union-unsized.rs b/src/test/compile-fail/union/union-unsized.rs
new file mode 100644
index 00000000000..a238eaf0525
--- /dev/null
+++ b/src/test/compile-fail/union/union-unsized.rs
@@ -0,0 +1,23 @@
+// 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(untagged_unions)]
+
+union U {
+    a: str, //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+    b: u8,
+}
+
+union W {
+    a: u8,
+    b: str, //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/union/union-with-drop-fields-lint.rs b/src/test/compile-fail/union/union-with-drop-fields-lint.rs
new file mode 100644
index 00000000000..87a72efbe08
--- /dev/null
+++ b/src/test/compile-fail/union/union-with-drop-fields-lint.rs
@@ -0,0 +1,40 @@
+// 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(untagged_unions)]
+#![allow(dead_code)]
+#![deny(unions_with_drop_fields)]
+
+union U {
+    a: u8, // OK
+}
+
+union W {
+    a: String, //~ ERROR union contains a field with possibly non-trivial drop code
+    b: String, // OK, only one field is reported
+}
+
+struct S(String);
+
+// `S` doesn't implement `Drop` trait, but still has non-trivial destructor
+union Y {
+    a: S, //~ ERROR union contains a field with possibly non-trivial drop code
+}
+
+// We don't know if `T` is trivially-destructable or not until trans
+union J<T> {
+    a: T, //~ ERROR union contains a field with possibly non-trivial drop code
+}
+
+union H<T: Copy> {
+    a: T, // OK, `T` is `Copy`, no destructor
+}
+
+fn main() {}
diff --git a/src/test/debuginfo/union-smoke.rs b/src/test/debuginfo/union-smoke.rs
new file mode 100644
index 00000000000..319927c979b
--- /dev/null
+++ b/src/test/debuginfo/union-smoke.rs
@@ -0,0 +1,50 @@
+// 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.
+
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:print u
+// gdb-check:$1 = {a = {__0 = 2 '\002', __1 = 2 '\002'}, b = 514}
+// gdb-command:print union_smoke::SU
+// gdb-check:$2 = {a = {__0 = 1 '\001', __1 = 1 '\001'}, b = 257}
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:run
+// lldb-command:print u
+// lldb-check:[...]$0 = { a = ('\x02', '\x02') b = 514 }
+// lldb-command:print union_smoke::SU
+// lldb-check:[...]$1 = 257
+
+#![allow(unused)]
+#![feature(omit_gdb_pretty_printer_section)]
+#![omit_gdb_pretty_printer_section]
+#![feature(untagged_unions)]
+
+union U {
+    a: (u8, u8),
+    b: u16,
+}
+
+static mut SU: U = U { a: (1, 1) };
+
+fn main() {
+    let u = U { b: (2 << 8) + 2 };
+    unsafe { SU = U { a: (1, 1) } }
+
+    zzz(); // #break
+}
+
+fn zzz() {()}
diff --git a/src/test/incremental/struct_change_field_name.rs b/src/test/incremental/struct_change_field_name.rs
index ba469c62002..c27294442e7 100644
--- a/src/test/incremental/struct_change_field_name.rs
+++ b/src/test/incremental/struct_change_field_name.rs
@@ -37,7 +37,7 @@ pub struct Y {
 #[rustc_dirty(label="TypeckItemBody", cfg="cfail2")]
 pub fn use_X() -> u32 {
     let x: X = X { x: 22 };
-    //[cfail2]~^ ERROR structure `X` has no field named `x`
+    //[cfail2]~^ ERROR struct `X` has no field named `x`
     x.x as u32
     //[cfail2]~^ ERROR attempted access of field `x`
 }
diff --git a/src/test/run-pass/union/auxiliary/union.rs b/src/test/run-pass/union/auxiliary/union.rs
new file mode 100644
index 00000000000..0231e38a729
--- /dev/null
+++ b/src/test/run-pass/union/auxiliary/union.rs
@@ -0,0 +1,16 @@
+// 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(untagged_unions)]
+
+pub union U {
+    pub a: u8,
+    pub b: u16,
+}
diff --git a/src/test/run-pass/union/union-backcomp.rs b/src/test/run-pass/union/union-backcomp.rs
new file mode 100644
index 00000000000..9394b618ddf
--- /dev/null
+++ b/src/test/run-pass/union/union-backcomp.rs
@@ -0,0 +1,27 @@
+// 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(untagged_unions)]
+
+fn union() {}
+
+fn main() {
+    union();
+
+    let union = 10;
+
+    union;
+
+    union as u8;
+
+    union U {
+        a: u8,
+    }
+}
diff --git a/src/test/run-pass/union/union-basic.rs b/src/test/run-pass/union/union-basic.rs
new file mode 100644
index 00000000000..d23af4b41b7
--- /dev/null
+++ b/src/test/run-pass/union/union-basic.rs
@@ -0,0 +1,68 @@
+// 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.
+
+// aux-build:union.rs
+
+#![feature(untagged_unions)]
+
+extern crate union;
+use std::mem::{size_of, align_of, zeroed};
+
+union U {
+    a: u8,
+    b: u16
+}
+
+fn local() {
+    assert_eq!(size_of::<U>(), 2);
+    assert_eq!(align_of::<U>(), 2);
+
+    let u = U { a: 10 };
+    unsafe {
+        assert_eq!(u.a, 10);
+        let U { a } = u;
+        assert_eq!(a, 10);
+    }
+
+    let mut w = U { b: 0 };
+    unsafe {
+        assert_eq!(w.a, 0);
+        assert_eq!(w.b, 0);
+        w.a = 1;
+        assert_eq!(w.a, 1);
+        assert_eq!(w.b, 1);
+    }
+}
+
+fn xcrate() {
+    assert_eq!(size_of::<union::U>(), 2);
+    assert_eq!(align_of::<union::U>(), 2);
+
+    let u = union::U { a: 10 };
+    unsafe {
+        assert_eq!(u.a, 10);
+        let union::U { a } = u;
+        assert_eq!(a, 10);
+    }
+
+    let mut w = union::U { b: 0 };
+    unsafe {
+        assert_eq!(w.a, 0);
+        assert_eq!(w.b, 0);
+        w.a = 1;
+        assert_eq!(w.a, 1);
+        assert_eq!(w.b, 1);
+    }
+}
+
+fn main() {
+    local();
+    xcrate();
+}
diff --git a/src/test/run-pass/union/union-c-interop.rs b/src/test/run-pass/union/union-c-interop.rs
new file mode 100644
index 00000000000..a9f97620ebd
--- /dev/null
+++ b/src/test/run-pass/union/union-c-interop.rs
@@ -0,0 +1,47 @@
+// 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(untagged_unions)]
+
+#[derive(Copy)]
+#[repr(C)]
+struct LARGE_INTEGER_U {
+    LowPart: u32,
+    HighPart: u32,
+}
+
+#[derive(Copy)]
+#[repr(C)]
+union LARGE_INTEGER {
+  __unnamed__: LARGE_INTEGER_U,
+  u: LARGE_INTEGER_U,
+  QuadPart: u64,
+}
+
+impl Clone for LARGE_INTEGER_U { fn clone(&self) -> Self { *self } }
+impl Clone for LARGE_INTEGER { fn clone(&self) -> Self { *self } }
+
+#[link(name = "rust_test_helpers")]
+extern "C" {
+    fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER;
+}
+
+fn main() {
+    unsafe {
+        let mut li = LARGE_INTEGER { QuadPart: 0 };
+        let li_c = increment_all_parts(li);
+        li.__unnamed__.LowPart += 1;
+        li.__unnamed__.HighPart += 1;
+        li.u.LowPart += 1;
+        li.u.HighPart += 1;
+        li.QuadPart += 1;
+        assert_eq!(li.QuadPart, li_c.QuadPart);
+    }
+}
diff --git a/src/test/run-pass/union/union-const-trans.rs b/src/test/run-pass/union/union-const-trans.rs
new file mode 100644
index 00000000000..bdae1a0eaf8
--- /dev/null
+++ b/src/test/run-pass/union/union-const-trans.rs
@@ -0,0 +1,27 @@
+// 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(untagged_unions)]
+
+union U {
+    a: u64,
+    b: u64,
+}
+
+const C: U = U { b: 10 };
+
+fn main() {
+    unsafe {
+        let a = C.a;
+        let b = C.b;
+        assert_eq!(a, 10);
+        assert_eq!(b, 10);
+     }
+}
diff --git a/src/test/run-pass/union/union-derive.rs b/src/test/run-pass/union/union-derive.rs
new file mode 100644
index 00000000000..b71c23990a4
--- /dev/null
+++ b/src/test/run-pass/union/union-derive.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// Some traits can be derived for unions.
+
+#![feature(untagged_unions)]
+
+#[derive(
+    Copy,
+)]
+union U {
+    a: u8,
+    b: u16,
+}
+
+impl Clone for U {
+    fn clone(&self) -> Self { *self }
+}
+
+fn main() {
+    let u = U { b: 0 };
+    let u1 = u;
+    let u2 = u.clone();
+}
diff --git a/src/test/run-pass/union/union-drop-assign.rs b/src/test/run-pass/union/union-drop-assign.rs
new file mode 100644
index 00000000000..0da68e43f32
--- /dev/null
+++ b/src/test/run-pass/union/union-drop-assign.rs
@@ -0,0 +1,44 @@
+// 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.
+
+// Drop works for union itself.
+
+#![feature(untagged_unions)]
+
+struct S;
+
+union U {
+    a: S
+}
+
+impl Drop for S {
+    fn drop(&mut self) {
+        unsafe { CHECK += 10; }
+    }
+}
+
+impl Drop for U {
+    fn drop(&mut self) {
+        unsafe { CHECK += 1; }
+    }
+}
+
+static mut CHECK: u8 = 0;
+
+fn main() {
+    unsafe {
+        let mut u = U { a: S };
+        assert_eq!(CHECK, 0);
+        u = U { a: S };
+        assert_eq!(CHECK, 1); // union itself is assigned, union is dropped, field is not dropped
+        u.a = S;
+        assert_eq!(CHECK, 11); // union field is assigned, field is dropped
+    }
+}
diff --git a/src/test/run-pass/union/union-drop.rs b/src/test/run-pass/union/union-drop.rs
new file mode 100644
index 00000000000..2ca68dc3b6e
--- /dev/null
+++ b/src/test/run-pass/union/union-drop.rs
@@ -0,0 +1,65 @@
+// 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.
+
+// Drop works for union itself.
+
+#![feature(untagged_unions)]
+
+struct S;
+
+union U {
+    a: u8
+}
+
+union W {
+    a: S,
+}
+
+union Y {
+    a: S,
+}
+
+impl Drop for S {
+    fn drop(&mut self) {
+        unsafe { CHECK += 10; }
+    }
+}
+
+impl Drop for U {
+    fn drop(&mut self) {
+        unsafe { CHECK += 1; }
+    }
+}
+
+impl Drop for W {
+    fn drop(&mut self) {
+        unsafe { CHECK += 1; }
+    }
+}
+
+static mut CHECK: u8 = 0;
+
+fn main() {
+    unsafe {
+        assert_eq!(CHECK, 0);
+        {
+            let u = U { a: 1 };
+        }
+        assert_eq!(CHECK, 1); // 1, dtor of U is called
+        {
+            let w = W { a: S };
+        }
+        assert_eq!(CHECK, 2); // 2, not 11, dtor of S is not called
+        {
+            let y = Y { a: S };
+        }
+        assert_eq!(CHECK, 2); // 2, not 12, dtor of S is not called
+    }
+}
diff --git a/src/test/run-pass/union/union-generic.rs b/src/test/run-pass/union/union-generic.rs
new file mode 100644
index 00000000000..9293805edbf
--- /dev/null
+++ b/src/test/run-pass/union/union-generic.rs
@@ -0,0 +1,43 @@
+// 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(untagged_unions)]
+
+union MaybeItem<T: Iterator> {
+    elem: T::Item,
+    none: (),
+}
+
+union U<A, B> {
+    a: A,
+    b: B,
+}
+
+unsafe fn union_transmute<A, B>(a: A) -> B {
+    U { a: a }.b
+}
+
+fn main() {
+    unsafe {
+        let u = U::<String, Vec<u8>> { a: String::from("abcd") };
+
+        assert_eq!(u.b.len(), 4);
+        assert_eq!(u.b[0], b'a');
+
+        let b = union_transmute::<(u8, u8), u16>((1, 1));
+        assert_eq!(b, (1 << 8) + 1);
+
+        let v: Vec<u8> = vec![1, 2, 3];
+        let mut i = v.iter();
+        i.next();
+        let mi = MaybeItem::<std::slice::Iter<_>> { elem: i.next().unwrap() };
+        assert_eq!(*mi.elem, 2);
+    }
+}
diff --git a/src/test/run-pass/union/union-inherent-method.rs b/src/test/run-pass/union/union-inherent-method.rs
new file mode 100644
index 00000000000..adea27bd254
--- /dev/null
+++ b/src/test/run-pass/union/union-inherent-method.rs
@@ -0,0 +1,24 @@
+// 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(untagged_unions)]
+
+union U {
+    a: u8,
+}
+
+impl U {
+    fn method(&self) -> u8 { unsafe { self.a } }
+}
+
+fn main() {
+    let u = U { a: 10 };
+    assert_eq!(u.method(), 10);
+}
diff --git a/src/test/run-pass/union/union-macro.rs b/src/test/run-pass/union/union-macro.rs
new file mode 100644
index 00000000000..a23fbc3be9e
--- /dev/null
+++ b/src/test/run-pass/union/union-macro.rs
@@ -0,0 +1,33 @@
+// 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(untagged_unions)]
+
+macro_rules! duplicate {
+   ($i: item) => {
+        mod m1 {
+            $i
+        }
+        mod m2 {
+            $i
+        }
+   }
+}
+
+duplicate! {
+    pub union U {
+        pub a: u8
+    }
+}
+
+fn main() {
+    let u1 = m1::U { a: 0 };
+    let u2 = m2::U { a: 0 };
+}
diff --git a/src/test/run-pass/union/union-overwrite.rs b/src/test/run-pass/union/union-overwrite.rs
new file mode 100644
index 00000000000..9389a6237bc
--- /dev/null
+++ b/src/test/run-pass/union/union-overwrite.rs
@@ -0,0 +1,80 @@
+// 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(untagged_unions)]
+
+#[repr(C)]
+struct Pair<T, U>(T, U);
+#[repr(C)]
+struct Triple<T>(T, T, T);
+
+#[repr(C)]
+union U<A, B> {
+    a: Pair<A, A>,
+    b: B,
+}
+
+#[repr(C)]
+union W<A, B> {
+    a: A,
+    b: B,
+}
+
+#[cfg(target_endian = "little")]
+unsafe fn check() {
+    let mut u = U::<u8, u16> { b: 0xDE_DE };
+    u.a.0 = 0xBE;
+    assert_eq!(u.b, 0xDE_BE);
+
+    let mut u = U::<u16, u32> { b: 0xDEAD_DEAD };
+    u.a.0 = 0xBEEF;
+    assert_eq!(u.b, 0xDEAD_BEEF);
+
+    let mut u = U::<u32, u64> { b: 0xDEADBEEF_DEADBEEF };
+    u.a.0 = 0xBAADF00D;
+    assert_eq!(u.b, 0xDEADBEEF_BAADF00D);
+
+    let mut w = W::<Pair<Triple<u8>, u8>, u32> { b: 0xDEAD_DEAD };
+    w.a.0 = Triple(0, 0, 0);
+    assert_eq!(w.b, 0xDE00_0000);
+
+    let mut w = W::<Pair<u8, Triple<u8>>, u32> { b: 0xDEAD_DEAD };
+    w.a.1 = Triple(0, 0, 0);
+    assert_eq!(w.b, 0x0000_00AD);
+}
+
+#[cfg(target_endian = "big")]
+unsafe fn check() {
+    let mut u = U::<u8, u16> { b: 0xDE_DE };
+    u.a.0 = 0xBE;
+    assert_eq!(u.b, 0xBE_DE);
+
+    let mut u = U::<u16, u32> { b: 0xDEAD_DEAD };
+    u.a.0 = 0xBEEF;
+    assert_eq!(u.b, 0xBEEF_DEAD);
+
+    let mut u = U::<u32, u64> { b: 0xDEADBEEF_DEADBEEF };
+    u.a.0 = 0xBAADF00D;
+    assert_eq!(u.b, 0xBAADF00D_DEADBEEF);
+
+    let mut w = W::<Pair<Triple<u8>, u8>, u32> { b: 0xDEAD_DEAD };
+    w.a.0 = Triple(0, 0, 0);
+    assert_eq!(w.b, 0x0000_00AD);
+
+    let mut w = W::<Pair<u8, Triple<u8>>, u32> { b: 0xDEAD_DEAD };
+    w.a.1 = Triple(0, 0, 0);
+    assert_eq!(w.b, 0xDE00_0000);
+}
+
+fn main() {
+    unsafe {
+        check();
+    }
+}
diff --git a/src/test/run-pass/union/union-packed.rs b/src/test/run-pass/union/union-packed.rs
new file mode 100644
index 00000000000..6a61280823e
--- /dev/null
+++ b/src/test/run-pass/union/union-packed.rs
@@ -0,0 +1,104 @@
+// 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(untagged_unions)]
+
+use std::mem::{size_of, size_of_val, align_of, align_of_val};
+
+struct S {
+    a: u16,
+    b: [u8; 3],
+}
+
+#[repr(packed)]
+struct Sp {
+    a: u16,
+    b: [u8; 3],
+}
+
+union U {
+    a: u16,
+    b: [u8; 3],
+}
+
+#[repr(packed)]
+union Up {
+    a: u16,
+    b: [u8; 3],
+}
+
+const CS: S = S { a: 0, b: [0, 0, 0] };
+const CSP: Sp = Sp { a: 0, b: [0, 0, 0] };
+const CU: U = U { b: [0, 0, 0] };
+const CUP: Up = Up { b: [0, 0, 0] };
+
+fn main() {
+    let s = S { a: 0, b: [0, 0, 0] };
+    assert_eq!(size_of::<S>(), 6);
+    assert_eq!(size_of_val(&s), 6);
+    assert_eq!(size_of_val(&CS), 6);
+    assert_eq!(align_of::<S>(), 2);
+    assert_eq!(align_of_val(&s), 2);
+    assert_eq!(align_of_val(&CS), 2);
+
+    let sp = Sp { a: 0, b: [0, 0, 0] };
+    assert_eq!(size_of::<Sp>(), 5);
+    assert_eq!(size_of_val(&sp), 5);
+    assert_eq!(size_of_val(&CSP), 5);
+    assert_eq!(align_of::<Sp>(), 1);
+    assert_eq!(align_of_val(&sp), 1);
+    assert_eq!(align_of_val(&CSP), 1);
+
+    let u = U { b: [0, 0, 0] };
+    assert_eq!(size_of::<U>(), 4);
+    assert_eq!(size_of_val(&u), 4);
+    assert_eq!(size_of_val(&CU), 4);
+    assert_eq!(align_of::<U>(), 2);
+    assert_eq!(align_of_val(&u), 2);
+    assert_eq!(align_of_val(&CU), 2);
+
+    let up = Up { b: [0, 0, 0] };
+    assert_eq!(size_of::<Up>(), 3);
+    assert_eq!(size_of_val(&up), 3);
+    assert_eq!(size_of_val(&CUP), 3);
+    assert_eq!(align_of::<Up>(), 1);
+    assert_eq!(align_of_val(&up), 1);
+    assert_eq!(align_of_val(&CUP), 1);
+
+    hybrid::check_hybrid();
+}
+
+mod hybrid {
+    use std::mem::size_of;
+
+    #[repr(packed)]
+    struct S1 {
+        a: u16,
+        b: u8,
+    }
+
+    #[repr(packed)]
+    union U {
+        s: S1,
+        c: u16,
+    }
+
+    #[repr(packed)]
+    struct S2 {
+        d: u8,
+        u: U,
+    }
+
+    pub fn check_hybrid() {
+        assert_eq!(size_of::<S1>(), 3);
+        assert_eq!(size_of::<U>(), 3);
+        assert_eq!(size_of::<S2>(), 4);
+    }
+}
diff --git a/src/test/run-pass/union/union-pat-refutability.rs b/src/test/run-pass/union/union-pat-refutability.rs
new file mode 100644
index 00000000000..e6144f35f1d
--- /dev/null
+++ b/src/test/run-pass/union/union-pat-refutability.rs
@@ -0,0 +1,62 @@
+// 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(untagged_unions)]
+
+#[repr(u32)]
+enum Tag { I, F }
+
+#[repr(C)]
+union U {
+    i: i32,
+    f: f32,
+}
+
+#[repr(C)]
+struct Value {
+    tag: Tag,
+    u: U,
+}
+
+fn is_zero(v: Value) -> bool {
+    unsafe {
+        match v {
+            Value { tag: Tag::I, u: U { i: 0 } } => true,
+            Value { tag: Tag::F, u: U { f: 0.0 } } => true,
+            _ => false,
+        }
+    }
+}
+
+union W {
+    a: u8,
+    b: u8,
+}
+
+fn refut(w: W) {
+    unsafe {
+        match w {
+            W { a: 10 } => {
+                panic!();
+            }
+            W { b } => {
+                assert_eq!(b, 11);
+            }
+        }
+    }
+}
+
+fn main() {
+    let v = Value { tag: Tag::I, u: U { i: 1 } };
+    assert_eq!(is_zero(v), false);
+
+    let w = W { a: 11 };
+    refut(w);
+}
diff --git a/src/test/run-pass/union/union-trait-impl.rs b/src/test/run-pass/union/union-trait-impl.rs
new file mode 100644
index 00000000000..a5a2be0133a
--- /dev/null
+++ b/src/test/run-pass/union/union-trait-impl.rs
@@ -0,0 +1,27 @@
+// 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(untagged_unions)]
+
+use std::fmt;
+
+union U {
+    a: u8
+}
+
+impl fmt::Display for U {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        unsafe { write!(f, "Oh hai {}", self.a) }
+    }
+}
+
+fn main() {
+    assert_eq!(U { a: 2 }.to_string(), "Oh hai 2");
+}
diff --git a/src/test/run-pass/union/union-transmute.rs b/src/test/run-pass/union/union-transmute.rs
new file mode 100644
index 00000000000..4eb66268ab8
--- /dev/null
+++ b/src/test/run-pass/union/union-transmute.rs
@@ -0,0 +1,40 @@
+// 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_float)]
+#![feature(float_extras)]
+#![feature(untagged_unions)]
+
+extern crate core;
+use core::num::Float;
+
+union U {
+    a: (u8, u8),
+    b: u16,
+}
+
+union W {
+    a: u32,
+    b: f32,
+}
+
+fn main() {
+    unsafe {
+        let mut u = U { a: (1, 1) };
+        assert_eq!(u.b, (1 << 8) + 1);
+        u.b = (2 << 8) + 2;
+        assert_eq!(u.a, (2, 2));
+
+        let mut w = W { a: 0b0_11111111_00000000000000000000000 };
+        assert_eq!(w.b, f32::infinity());
+        w.b = f32::neg_infinity();
+        assert_eq!(w.a, 0b1_11111111_00000000000000000000000);
+    }
+}
diff --git a/src/test/run-pass/union/union-with-drop-fields-lint.rs b/src/test/run-pass/union/union-with-drop-fields-lint.rs
new file mode 100644
index 00000000000..5a1424830d0
--- /dev/null
+++ b/src/test/run-pass/union/union-with-drop-fields-lint.rs
@@ -0,0 +1,42 @@
+// 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.
+
+// ignore-pretty
+
+#![feature(untagged_unions)]
+#![allow(dead_code)]
+#![allow(unions_with_drop_fields)]
+
+union U {
+    a: u8, // OK
+}
+
+union W {
+    a: String, // OK
+    b: String, // OK
+}
+
+struct S(String);
+
+// `S` doesn't implement `Drop` trait, but still has non-trivial destructor
+union Y {
+    a: S, // OK
+}
+
+// We don't know if `T` is trivially-destructable or not until trans
+union J<T> {
+    a: T, // OK
+}
+
+union H<T: Copy> {
+    a: T, // OK
+}
+
+fn main() {}
diff --git a/src/test/rustdoc/union.rs b/src/test/rustdoc/union.rs
new file mode 100644
index 00000000000..0dcc9098ad7
--- /dev/null
+++ b/src/test/rustdoc/union.rs
@@ -0,0 +1,20 @@
+// 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(untagged_unions)]
+
+// @has union/union.U.html
+pub union U {
+    // @has - //pre "pub a: u8"
+    pub a: u8,
+    // @has - //pre "// some fields omitted"
+    // @!has - //pre "b: u16"
+    b: u16,
+}