diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1a5ef9b3ba7..74d46c1525c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1073,6 +1073,8 @@ fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let def = tcx.adt_def(def_id); def.destructor(tcx); // force the destructor to be evaluated check_representable(tcx, span, def_id); + + check_packed(tcx, span, def_id); } pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) { @@ -1477,11 +1479,11 @@ fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) if tcx.adt_def(def_id).repr.packed() { if tcx.adt_def(def_id).repr.align > 0 { struct_span_err!(tcx.sess, sp, E0587, - "struct has conflicting packed and align representation hints").emit(); + "type has conflicting packed and align representation hints").emit(); } else if check_packed_inner(tcx, def_id, &mut Vec::new()) { struct_span_err!(tcx.sess, sp, E0588, - "packed struct cannot transitively contain a `[repr(align)]` struct").emit(); + "packed type cannot transitively contain a `[repr(align)]` type").emit(); } } } @@ -1495,7 +1497,7 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return false; } match t.sty { - ty::TyAdt(def, substs) if def.is_struct() => { + ty::TyAdt(def, substs) if def.is_struct() || def.is_union() => { if tcx.adt_def(def.did).repr.align > 0 { return true; } diff --git a/src/test/compile-fail/conflicting-repr-hints.rs b/src/test/compile-fail/conflicting-repr-hints.rs index e4a9205409b..12ac8fb57b1 100644 --- a/src/test/compile-fail/conflicting-repr-hints.rs +++ b/src/test/compile-fail/conflicting-repr-hints.rs @@ -28,14 +28,31 @@ enum D { D } struct E(i32); #[repr(packed, align(8))] -struct F(i32); //~ ERROR struct has conflicting packed and align representation hints +struct F(i32); //~ ERROR type has conflicting packed and align representation hints #[repr(packed)] #[repr(align(8))] -struct G(i32); //~ ERROR struct has conflicting packed and align representation hints +struct G(i32); //~ ERROR type has conflicting packed and align representation hints #[repr(align(8))] #[repr(packed)] -struct H(i32); //~ ERROR struct has conflicting packed and align representation hints +struct H(i32); //~ ERROR type has conflicting packed and align representation hints + +#[repr(packed, align(8))] +union X { //~ ERROR type has conflicting packed and align representation hints + i: i32 +} + +#[repr(packed)] +#[repr(align(8))] +union Y { //~ ERROR type has conflicting packed and align representation hints + i: i32 +} + +#[repr(align(8))] +#[repr(packed)] +union Z { //~ ERROR type has conflicting packed and align representation hints + i: i32 +} fn main() {} diff --git a/src/test/compile-fail/repr-packed-contains-align.rs b/src/test/compile-fail/repr-packed-contains-align.rs index c584dcf3e59..78d43064ea3 100644 --- a/src/test/compile-fail/repr-packed-contains-align.rs +++ b/src/test/compile-fail/repr-packed-contains-align.rs @@ -9,17 +9,53 @@ // except according to those terms. #![feature(attr_literals)] #![feature(repr_align)] +#![feature(untagged_unions)] #![allow(dead_code)] #[repr(align(16))] -struct A(i32); +struct SA(i32); -struct B(A); +struct SB(SA); + +#[repr(align(16))] +union UA { + i: i32 +} + +union UB { + a: UA +} #[repr(packed)] -struct C(A); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct +struct SC(SA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type #[repr(packed)] -struct D(B); //~ ERROR: packed struct cannot transitively contain a `[repr(align)]` struct +struct SD(SB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + +#[repr(packed)] +struct SE(UA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + +#[repr(packed)] +struct SF(UB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + +#[repr(packed)] +union UC { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + a: UA +} + +#[repr(packed)] +union UD { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + n: UB +} + +#[repr(packed)] +union UE { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + a: SA +} + +#[repr(packed)] +union UF { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type + n: SB +} fn main() {}