From 73c73e4a9509e2ecf593589442bff802dd53c9b4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 18 May 2017 00:22:52 +0300 Subject: [PATCH] Stabilize unions with `Copy` fields and no destructor --- src/libcollections/lib.rs | 1 - src/librustc/middle/stability.rs | 21 ++++++++++++++++++ src/librustc_data_structures/lib.rs | 1 - src/libsyntax/feature_gate.rs | 6 ----- .../borrowck/borrowck-union-borrow-nested.rs | 4 ---- .../borrowck/borrowck-union-borrow.rs | 2 -- .../borrowck/borrowck-union-uninitialized.rs | 2 -- .../privacy/union-field-privacy-1.rs | 2 -- .../privacy/union-field-privacy-2.rs | 2 -- .../compile-fail/union/union-const-eval.rs | 2 -- .../compile-fail/union/union-const-pat.rs | 2 -- src/test/compile-fail/union/union-derive.rs | 2 -- src/test/compile-fail/union/union-empty.rs | 2 -- .../compile-fail/union/union-feature-gate.rs | 22 ++++++++++++++++++- src/test/compile-fail/union/union-fields.rs | 2 -- src/test/compile-fail/union/union-generic.rs | 2 -- .../union/union-lint-dead-code.rs | 1 - src/test/compile-fail/union/union-repr-c.rs | 1 - .../compile-fail/union/union-suggest-field.rs | 2 -- src/test/debuginfo/union-smoke.rs | 1 - src/test/run-pass/union/auxiliary/union.rs | 2 -- src/test/run-pass/union/union-backcomp.rs | 2 -- src/test/run-pass/union/union-basic.rs | 2 -- src/test/run-pass/union/union-c-interop.rs | 2 -- src/test/run-pass/union/union-const-trans.rs | 2 -- .../run-pass/union/union-inherent-method.rs | 2 -- src/test/run-pass/union/union-macro.rs | 2 -- .../run-pass/union/union-pat-refutability.rs | 2 -- src/test/run-pass/union/union-trait-impl.rs | 2 -- src/test/run-pass/union/union-transmute.rs | 2 -- src/test/rustdoc/union.rs | 2 -- src/test/ui/print_type_sizes/packed.rs | 2 -- 32 files changed, 42 insertions(+), 62 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 842f2f44fff..72ff6575ca1 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 d74877e355a..e27990c29cf 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -625,6 +625,27 @@ fn visit_item(&mut self, item: &'tcx hir::Item) { } } + // 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 c254dfc48d2..83cd5cef00c 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 ca579409be4..c119fad1b73 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1207,12 +1207,6 @@ fn visit_item(&mut self, i: &'a ast::Item) { } } - 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 8b6b8d9ecb0..6298c87453c 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 ecc698acc31..20b882e1f80 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 36e062f8464..81376a1a169 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 807be619f6c..eeebb1b737a 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 e26b5e99ec1..d6bb765202d 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 b2bf173c59c..ee4d9fe99ee 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 3d168980ed2..5f75e3cc4a2 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 26dbdfd0b41..ffd290fb073 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 ce5bbf60fee..1f499c49a68 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 0c2165871f6..8a0490cdc6b 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 3ee95c2ef42..b5d582a5746 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 e6586b0fb7f..8bd422b42d8 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 7a552c8f8b7..a64187c5f23 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 d7dfb126c93..15a4197fe94 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 3c355989b82..65c7c980b8a 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 0b2544151fd..433196b526c 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 0231e38a729..2c4945622ab 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 0f8c996bebd..b706a81850c 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 dc14c12b6a2..5e5b2d4d7ce 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 13dfd414615..b3df7d658b1 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 bdae1a0eaf8..77270364bb5 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 adea27bd254..a88fdc57a3e 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 a23fbc3be9e..b6141ae82c3 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 e6144f35f1d..81607236c9e 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 a5a2be0133a..1cdaff2cab7 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 7a0b4c6aaca..7233687aaab 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 0dcc9098ad7..2eb25d9b7dd 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 cd7ef86d70e..7f278e71b21 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)] -- 2.44.0