Skip to content

Commit 3d7a6fe

Browse files
committed
Prevent repr(C, u8) from triggering a warning on non-clike enums
1 parent 8293fe9 commit 3d7a6fe

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/librustc/hir/check_attr.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ impl<'a> CheckAttrVisitor<'a> {
7575
}
7676
};
7777

78-
let mut conflicting_reprs = 0;
78+
let mut int_reprs = 0;
79+
let mut is_c = false;
80+
let mut is_simd = false;
7981

8082
for word in words {
8183

@@ -86,7 +88,7 @@ impl<'a> CheckAttrVisitor<'a> {
8688

8789
let (message, label) = match &*name.as_str() {
8890
"C" => {
89-
conflicting_reprs += 1;
91+
is_c = true;
9092
if target != Target::Struct &&
9193
target != Target::Union &&
9294
target != Target::Enum {
@@ -108,7 +110,7 @@ impl<'a> CheckAttrVisitor<'a> {
108110
}
109111
}
110112
"simd" => {
111-
conflicting_reprs += 1;
113+
is_simd = true;
112114
if target != Target::Struct {
113115
("attribute should be applied to struct",
114116
"a struct")
@@ -128,7 +130,7 @@ impl<'a> CheckAttrVisitor<'a> {
128130
"i8" | "u8" | "i16" | "u16" |
129131
"i32" | "u32" | "i64" | "u64" |
130132
"isize" | "usize" => {
131-
conflicting_reprs += 1;
133+
int_reprs += 1;
132134
if target != Target::Enum {
133135
("attribute should be applied to enum",
134136
"an enum")
@@ -142,7 +144,11 @@ impl<'a> CheckAttrVisitor<'a> {
142144
.span_label(item.span, format!("not {}", label))
143145
.emit();
144146
}
145-
if conflicting_reprs > 1 {
147+
148+
// Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8)
149+
if (int_reprs > 1)
150+
|| (is_simd && is_c)
151+
|| (int_reprs == 1 && is_c && is_c_like_enum(item)) {
146152
span_warn!(self.sess, attr.span, E0566,
147153
"conflicting representation hints");
148154
}
@@ -162,3 +168,17 @@ impl<'a> Visitor<'a> for CheckAttrVisitor<'a> {
162168
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
163169
visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate);
164170
}
171+
172+
fn is_c_like_enum(item: &ast::Item) -> bool {
173+
if let ast::ItemKind::Enum(ref def, _) = item.node {
174+
for variant in &def.variants {
175+
match variant.node.data {
176+
ast::VariantData::Unit(_) => { /* continue */ }
177+
_ => { return false; }
178+
}
179+
}
180+
true
181+
} else {
182+
false
183+
}
184+
}

0 commit comments

Comments
 (0)