Skip to content

Commit 200c4d0

Browse files
committed
Better detection of repr packed and align
Fixes issue #43317.
1 parent 504328a commit 200c4d0

File tree

5 files changed

+21
-19
lines changed

5 files changed

+21
-19
lines changed

src/librustc/diagnostics.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2025,5 +2025,4 @@ register_diagnostics! {
20252025
E0490, // a value of type `..` is borrowed for too long
20262026
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
20272027
E0566, // conflicting representation hints
2028-
E0587, // conflicting packed and align representation hints
20292028
}

src/librustc/hir/check_attr.rs

-8
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ impl<'a> CheckAttrVisitor<'a> {
7676
};
7777

7878
let mut conflicting_reprs = 0;
79-
let mut found_packed = false;
80-
let mut found_align = false;
8179

8280
for word in words {
8381

@@ -106,7 +104,6 @@ impl<'a> CheckAttrVisitor<'a> {
106104
("attribute should be applied to struct or union",
107105
"a struct or union")
108106
} else {
109-
found_packed = true;
110107
continue
111108
}
112109
}
@@ -120,7 +117,6 @@ impl<'a> CheckAttrVisitor<'a> {
120117
}
121118
}
122119
"align" => {
123-
found_align = true;
124120
if target != Target::Struct &&
125121
target != Target::Union {
126122
("attribute should be applied to struct or union",
@@ -150,10 +146,6 @@ impl<'a> CheckAttrVisitor<'a> {
150146
span_warn!(self.sess, attr.span, E0566,
151147
"conflicting representation hints");
152148
}
153-
if found_align && found_packed {
154-
struct_span_err!(self.sess, attr.span, E0587,
155-
"conflicting packed and align representation hints").emit();
156-
}
157149
}
158150
}
159151

src/librustc_typeck/check/mod.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -1063,11 +1063,7 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10631063
check_simd(tcx, span, def_id);
10641064
}
10651065

1066-
// if struct is packed and not aligned, check fields for alignment.
1067-
// Checks for combining packed and align attrs on single struct are done elsewhere.
1068-
if tcx.adt_def(def_id).repr.packed() && tcx.adt_def(def_id).repr.align == 0 {
1069-
check_packed(tcx, span, def_id);
1070-
}
1066+
check_packed(tcx, span, def_id);
10711067
}
10721068

10731069
fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -1478,9 +1474,15 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId
14781474
}
14791475

14801476
fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
1481-
if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1482-
struct_span_err!(tcx.sess, sp, E0588,
1483-
"packed struct cannot transitively contain a `[repr(align)]` struct").emit();
1477+
if tcx.adt_def(def_id).repr.packed() {
1478+
if tcx.adt_def(def_id).repr.align > 0 {
1479+
struct_span_err!(tcx.sess, sp, E0587,
1480+
"struct has conflicting packed and align representation hints").emit();
1481+
}
1482+
else if check_packed_inner(tcx, def_id, &mut Vec::new()) {
1483+
struct_span_err!(tcx.sess, sp, E0588,
1484+
"packed struct cannot transitively contain a `[repr(align)]` struct").emit();
1485+
}
14841486
}
14851487
}
14861488

src/librustc_typeck/diagnostics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4663,6 +4663,7 @@ register_diagnostics! {
46634663
// but `{}` was found in the type `{}`
46644664
E0567, // auto traits can not have type parameters
46654665
E0568, // auto-traits can not have predicates,
4666+
E0587, // struct has conflicting packed and align representation hints
46664667
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
46674668
E0592, // duplicate definitions with name `{}`
46684669
// E0613, // Removed (merged with E0609)

src/test/compile-fail/conflicting-repr-hints.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,15 @@ enum D { D }
2727
#[repr(C, packed)]
2828
struct E(i32);
2929

30-
#[repr(packed, align(8))] //~ ERROR conflicting packed and align representation hints
31-
struct F(i32);
30+
#[repr(packed, align(8))]
31+
struct F(i32); //~ ERROR struct has conflicting packed and align representation hints
32+
33+
#[repr(packed)]
34+
#[repr(align(8))]
35+
struct G(i32); //~ ERROR struct has conflicting packed and align representation hints
36+
37+
#[repr(align(8))]
38+
#[repr(packed)]
39+
struct H(i32); //~ ERROR struct has conflicting packed and align representation hints
3240

3341
fn main() {}

0 commit comments

Comments
 (0)