diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 842f2f44fff9e..72ff6575ca137 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -65,7 +65,6 @@ #![feature(trusted_len)] #![feature(unicode)] #![feature(unique)] -#![feature(untagged_unions)] #![cfg_attr(not(test), feature(str_checked_slicing))] #![cfg_attr(test, feature(rand, test))] #![feature(offset_to)] diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d74877e355a79..e27990c29cf9e 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -625,6 +625,27 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { } } + // There's no good place to insert stability check for non-Copy unions, + // so semi-randomly perform it here in stability.rs + hir::ItemUnion(..) if !self.tcx.sess.features.borrow().untagged_unions => { + let def_id = self.tcx.hir.local_def_id(item.id); + let adt_def = self.tcx.adt_def(def_id); + let ty = self.tcx.type_of(def_id); + + if adt_def.has_dtor(self.tcx) { + emit_feature_err(&self.tcx.sess.parse_sess, + "untagged_unions", item.span, GateIssue::Language, + "unions with `Drop` implementations are unstable"); + } else { + let param_env = self.tcx.param_env(def_id); + if !param_env.can_type_implement_copy(self.tcx, ty, item.span).is_ok() { + emit_feature_err(&self.tcx.sess.parse_sess, + "untagged_unions", item.span, GateIssue::Language, + "unions with non-`Copy` fields are unstable"); + } + } + } + _ => (/* pass */) } intravisit::walk_item(self, item); diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index c254dfc48d225..83cd5cef00cfe 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -29,7 +29,6 @@ #![feature(nonzero)] #![feature(unboxed_closures)] #![feature(fn_traits)] -#![feature(untagged_unions)] #![feature(associated_consts)] #![feature(unsize)] #![feature(i128_type)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ca579409be430..c119fad1b736e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1207,12 +1207,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Union(..) => { - gate_feature_post!(&self, untagged_unions, - i.span, - "unions are unstable and possibly buggy"); - } - ast::ItemKind::DefaultImpl(..) => { gate_feature_post!(&self, optin_builtin_traits, i.span, diff --git a/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs b/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs index 8b6b8d9ecb08e..6298c87453ca6 100644 --- a/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs +++ b/src/test/compile-fail/borrowck/borrowck-union-borrow-nested.rs @@ -8,10 +8,6 @@ // 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, diff --git a/src/test/compile-fail/borrowck/borrowck-union-borrow.rs b/src/test/compile-fail/borrowck/borrowck-union-borrow.rs index ecc698acc317f..20b882e1f807c 100644 --- a/src/test/compile-fail/borrowck/borrowck-union-borrow.rs +++ b/src/test/compile-fail/borrowck/borrowck-union-borrow.rs @@ -10,8 +10,6 @@ // ignore-tidy-linelength -#![feature(untagged_unions)] - #[derive(Clone, Copy)] union U { a: u8, diff --git a/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs b/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs index 36e062f8464e9..81376a1a169d4 100644 --- a/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs +++ b/src/test/compile-fail/borrowck/borrowck-union-uninitialized.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - struct S { a: u8, } diff --git a/src/test/compile-fail/privacy/union-field-privacy-1.rs b/src/test/compile-fail/privacy/union-field-privacy-1.rs index 807be619f6c5f..eeebb1b737a94 100644 --- a/src/test/compile-fail/privacy/union-field-privacy-1.rs +++ b/src/test/compile-fail/privacy/union-field-privacy-1.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - mod m { pub union U { pub a: u8, diff --git a/src/test/compile-fail/privacy/union-field-privacy-2.rs b/src/test/compile-fail/privacy/union-field-privacy-2.rs index e26b5e99ec1a5..d6bb765202da5 100644 --- a/src/test/compile-fail/privacy/union-field-privacy-2.rs +++ b/src/test/compile-fail/privacy/union-field-privacy-2.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - mod m { pub union U { pub a: u8, diff --git a/src/test/compile-fail/union/union-const-eval.rs b/src/test/compile-fail/union/union-const-eval.rs index b2bf173c59c86..ee4d9fe99eeb8 100644 --- a/src/test/compile-fail/union/union-const-eval.rs +++ b/src/test/compile-fail/union/union-const-eval.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - union U { a: usize, b: usize, diff --git a/src/test/compile-fail/union/union-const-pat.rs b/src/test/compile-fail/union/union-const-pat.rs index 3d168980ed246..5f75e3cc4a2d6 100644 --- a/src/test/compile-fail/union/union-const-pat.rs +++ b/src/test/compile-fail/union/union-const-pat.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - union U { a: usize, b: usize, diff --git a/src/test/compile-fail/union/union-derive.rs b/src/test/compile-fail/union/union-derive.rs index 26dbdfd0b4118..ffd290fb073db 100644 --- a/src/test/compile-fail/union/union-derive.rs +++ b/src/test/compile-fail/union/union-derive.rs @@ -10,8 +10,6 @@ // Most traits cannot be derived for unions. -#![feature(untagged_unions)] - #[derive( PartialEq, //~ ERROR this trait cannot be derived for unions PartialOrd, //~ ERROR this trait cannot be derived for unions diff --git a/src/test/compile-fail/union/union-empty.rs b/src/test/compile-fail/union/union-empty.rs index ce5bbf60fee25..1f499c49a6870 100644 --- a/src/test/compile-fail/union/union-empty.rs +++ b/src/test/compile-fail/union/union-empty.rs @@ -8,8 +8,6 @@ // 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 index 0c2165871f6db..8a0490cdc6b6d 100644 --- a/src/test/compile-fail/union/union-feature-gate.rs +++ b/src/test/compile-fail/union/union-feature-gate.rs @@ -10,8 +10,28 @@ // gate-test-untagged_unions -union U { //~ ERROR unions are unstable and possibly buggy +union U1 { // OK a: u8, } +union U2 { // OK + a: T, +} + +union U3 { //~ ERROR unions with non-`Copy` fields are unstable + a: String, +} + +union U4 { //~ ERROR unions with non-`Copy` fields are unstable + a: T, +} + +union U5 { //~ ERROR unions with `Drop` implementations are unstable + a: u8, +} + +impl Drop for U5 { + fn drop(&mut self) {} +} + fn main() {} diff --git a/src/test/compile-fail/union/union-fields.rs b/src/test/compile-fail/union/union-fields.rs index 3ee95c2ef4258..b5d582a5746f7 100644 --- a/src/test/compile-fail/union/union-fields.rs +++ b/src/test/compile-fail/union/union-fields.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - union U { a: u8, b: u16, diff --git a/src/test/compile-fail/union/union-generic.rs b/src/test/compile-fail/union/union-generic.rs index e6586b0fb7f6a..8bd422b42d879 100644 --- a/src/test/compile-fail/union/union-generic.rs +++ b/src/test/compile-fail/union/union-generic.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - use std::rc::Rc; union U { diff --git a/src/test/compile-fail/union/union-lint-dead-code.rs b/src/test/compile-fail/union/union-lint-dead-code.rs index 7a552c8f8b76a..a64187c5f2344 100644 --- a/src/test/compile-fail/union/union-lint-dead-code.rs +++ b/src/test/compile-fail/union/union-lint-dead-code.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] #![deny(dead_code)] union Foo { diff --git a/src/test/compile-fail/union/union-repr-c.rs b/src/test/compile-fail/union/union-repr-c.rs index d7dfb126c9324..15a4197fe94c9 100644 --- a/src/test/compile-fail/union/union-repr-c.rs +++ b/src/test/compile-fail/union/union-repr-c.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] #![allow(unused)] #![deny(improper_ctypes)] diff --git a/src/test/compile-fail/union/union-suggest-field.rs b/src/test/compile-fail/union/union-suggest-field.rs index 3c355989b82f0..65c7c980b8ac2 100644 --- a/src/test/compile-fail/union/union-suggest-field.rs +++ b/src/test/compile-fail/union/union-suggest-field.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - union U { principal: u8, } diff --git a/src/test/debuginfo/union-smoke.rs b/src/test/debuginfo/union-smoke.rs index 0b2544151fd32..433196b526c5c 100644 --- a/src/test/debuginfo/union-smoke.rs +++ b/src/test/debuginfo/union-smoke.rs @@ -34,7 +34,6 @@ #![allow(unused)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] -#![feature(untagged_unions)] union U { a: (u8, u8), diff --git a/src/test/run-pass/union/auxiliary/union.rs b/src/test/run-pass/union/auxiliary/union.rs index 0231e38a729b7..2c4945622abdc 100644 --- a/src/test/run-pass/union/auxiliary/union.rs +++ b/src/test/run-pass/union/auxiliary/union.rs @@ -8,8 +8,6 @@ // 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 index 0f8c996bebda8..b706a81850ce8 100644 --- a/src/test/run-pass/union/union-backcomp.rs +++ b/src/test/run-pass/union/union-backcomp.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - macro_rules! union { () => (struct S;) } diff --git a/src/test/run-pass/union/union-basic.rs b/src/test/run-pass/union/union-basic.rs index dc14c12b6a22e..5e5b2d4d7ce7b 100644 --- a/src/test/run-pass/union/union-basic.rs +++ b/src/test/run-pass/union/union-basic.rs @@ -13,8 +13,6 @@ // FIXME: This test case makes little-endian assumptions. // ignore-s390x -#![feature(untagged_unions)] - extern crate union; use std::mem::{size_of, align_of, zeroed}; diff --git a/src/test/run-pass/union/union-c-interop.rs b/src/test/run-pass/union/union-c-interop.rs index 13dfd414615c5..b3df7d658b15f 100644 --- a/src/test/run-pass/union/union-c-interop.rs +++ b/src/test/run-pass/union/union-c-interop.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - #[derive(Clone, Copy)] #[repr(C)] struct LARGE_INTEGER_U { diff --git a/src/test/run-pass/union/union-const-trans.rs b/src/test/run-pass/union/union-const-trans.rs index bdae1a0eaf88f..77270364bb5e9 100644 --- a/src/test/run-pass/union/union-const-trans.rs +++ b/src/test/run-pass/union/union-const-trans.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - union U { a: u64, b: u64, diff --git a/src/test/run-pass/union/union-inherent-method.rs b/src/test/run-pass/union/union-inherent-method.rs index adea27bd25462..a88fdc57a3ef4 100644 --- a/src/test/run-pass/union/union-inherent-method.rs +++ b/src/test/run-pass/union/union-inherent-method.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - union U { a: u8, } diff --git a/src/test/run-pass/union/union-macro.rs b/src/test/run-pass/union/union-macro.rs index a23fbc3be9e2c..b6141ae82c371 100644 --- a/src/test/run-pass/union/union-macro.rs +++ b/src/test/run-pass/union/union-macro.rs @@ -8,8 +8,6 @@ // 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 { diff --git a/src/test/run-pass/union/union-pat-refutability.rs b/src/test/run-pass/union/union-pat-refutability.rs index e6144f35f1d54..81607236c9ecd 100644 --- a/src/test/run-pass/union/union-pat-refutability.rs +++ b/src/test/run-pass/union/union-pat-refutability.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - #[repr(u32)] enum Tag { I, F } diff --git a/src/test/run-pass/union/union-trait-impl.rs b/src/test/run-pass/union/union-trait-impl.rs index a5a2be0133aba..1cdaff2cab7c8 100644 --- a/src/test/run-pass/union/union-trait-impl.rs +++ b/src/test/run-pass/union/union-trait-impl.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - use std::fmt; union U { diff --git a/src/test/run-pass/union/union-transmute.rs b/src/test/run-pass/union/union-transmute.rs index 7a0b4c6aaca49..7233687aaab53 100644 --- a/src/test/run-pass/union/union-transmute.rs +++ b/src/test/run-pass/union/union-transmute.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(untagged_unions)] - extern crate core; use core::f32; diff --git a/src/test/rustdoc/union.rs b/src/test/rustdoc/union.rs index 0dcc9098ad75c..2eb25d9b7ddac 100644 --- a/src/test/rustdoc/union.rs +++ b/src/test/rustdoc/union.rs @@ -8,8 +8,6 @@ // 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" diff --git a/src/test/ui/print_type_sizes/packed.rs b/src/test/ui/print_type_sizes/packed.rs index cd7ef86d70ee3..7f278e71b21c6 100644 --- a/src/test/ui/print_type_sizes/packed.rs +++ b/src/test/ui/print_type_sizes/packed.rs @@ -18,8 +18,6 @@ // aligned (while on most it is 8-byte aligned) and so the resulting // padding and overall computed sizes can be quite different. -#![feature(untagged_unions)] - #![allow(dead_code)] #[derive(Default)]