Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[beta] Backport union stabilization PRs #42328

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bootstrap/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub const CFG_RELEASE_NUM: &'static str = "1.18.0";
// An optional number to put after the label, e.g. '.2' -> '-beta.2'
// Be sure to make this starts with a dot to conform to semver pre-release
// versions (section 9)
pub const CFG_PRERELEASE_VERSION: &'static str = ".4";
pub const CFG_PRERELEASE_VERSION: &'static str = ".5";

pub struct GitInfo {
inner: Option<Info>,
Expand Down
1 change: 0 additions & 1 deletion src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,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)]
Expand Down
24 changes: 24 additions & 0 deletions src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn type_is_unsafe_function(ty: Ty) -> bool {
struct EffectCheckVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
body_id: hir::BodyId,

/// Whether we're in an unsafe context.
unsafe_context: UnsafeContext,
Expand Down Expand Up @@ -99,10 +100,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {

fn visit_nested_body(&mut self, body: hir::BodyId) {
let old_tables = self.tables;
let old_body_id = self.body_id;
self.tables = self.tcx.body_tables(body);
self.body_id = body;
let body = self.tcx.hir.body(body);
self.visit_body(body);
self.tables = old_tables;
self.body_id = old_body_id;
}

fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
Expand Down Expand Up @@ -218,6 +222,25 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
}
}
}
hir::ExprAssign(ref lhs, ref rhs) => {
if let hir::ExprField(ref base_expr, field) = lhs.node {
if let ty::TyAdt(adt, ..) = self.tables.expr_ty_adjusted(base_expr).sty {
if adt.is_union() {
let field_ty = self.tables.expr_ty_adjusted(lhs);
let owner_id = self.tcx.hir.body_owner(self.body_id);
let param_env = ty::ParameterEnvironment::for_item(self.tcx, owner_id);
if field_ty.moves_by_default(self.tcx, &param_env, field.span) {
self.require_unsafe(field.span,
"assignment to non-`Copy` union field");
}
// Do not walk the field expr again.
intravisit::walk_expr(self, base_expr);
intravisit::walk_expr(self, rhs);
return
}
}
}
}
_ => {}
}

Expand All @@ -243,6 +266,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = EffectCheckVisitor {
tcx: tcx,
tables: &ty::TypeckTables::empty(),
body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID },
unsafe_context: UnsafeContext::new(SafeContext),
};

Expand Down
21 changes: 21 additions & 0 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,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.lookup_adt_def(def_id);
let ty = self.tcx.item_type(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 = ty::ParameterEnvironment::for_item(self.tcx, item.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);
Expand Down
1 change: 0 additions & 1 deletion src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(fn_traits)]
#![feature(untagged_unions)]
#![feature(associated_consts)]
#![feature(unsize)]
#![feature(i128_type)]
Expand Down
6 changes: 0 additions & 6 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,12 +1202,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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/borrowck/borrowck-union-borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

// ignore-tidy-linelength

#![feature(untagged_unions)]

#[derive(Clone, Copy)]
union U {
a: u8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/privacy/union-field-privacy-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/privacy/union-field-privacy-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-const-eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-const-pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
22 changes: 21 additions & 1 deletion src/test/compile-fail/union/union-feature-gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,28 @@

// gate-test-untagged_unions

union U { //~ ERROR unions are unstable and possibly buggy
union U1 { // OK
a: u8,
}

union U2<T: Copy> { // OK
a: T,
}

union U3 { //~ ERROR unions with non-`Copy` fields are unstable
a: String,
}

union U4<T> { //~ 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() {}
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Copy> {
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/union/union-lint-dead-code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/union/union-repr-c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]

Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/union/union-suggest-field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
45 changes: 38 additions & 7 deletions src/test/compile-fail/union/union-unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,46 @@

#![feature(untagged_unions)]

union U {
union U1 {
a: u8
}

union U2 {
a: String
}

union U3<T> {
a: T
}

union U4<T: Copy> {
a: T
}

fn generic_noncopy<T: Default>() {
let mut u3 = U3 { a: T::default() };
u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field requires unsafe
}

fn generic_copy<T: Copy + Default>() {
let mut u3 = U3 { a: T::default() };
u3.a = T::default(); // OK
let mut u4 = U4 { a: T::default() };
u4.a = T::default(); // OK
}

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
let mut u1 = U1 { a: 10 }; // OK
let a = u1.a; //~ ERROR access to union field requires unsafe
u1.a = 11; // OK
let U1 { a } = u1; //~ ERROR matching on union field requires unsafe
if let U1 { a: 12 } = u1 {} //~ ERROR matching on union field requires unsafe
// let U1 { .. } = u1; // OK

let mut u2 = U2 { a: String::from("old") }; // OK
u2.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
let mut u3 = U3 { a: 0 }; // OK
u3.a = 1; // OK
let mut u3 = U3 { a: String::from("old") }; // OK
u3.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
}
1 change: 0 additions & 1 deletion src/test/debuginfo/union-smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/union/auxiliary/union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/union/union-backcomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;)
}
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/union/union-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/union/union-c-interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/union/union-const-trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/union/union-inherent-method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
Loading