@@ -75,7 +75,9 @@ impl<'a> CheckAttrVisitor<'a> {
75
75
}
76
76
} ;
77
77
78
- let mut conflicting_reprs = 0 ;
78
+ let mut int_reprs = 0 ;
79
+ let mut is_c = false ;
80
+ let mut is_simd = false ;
79
81
80
82
for word in words {
81
83
@@ -86,7 +88,7 @@ impl<'a> CheckAttrVisitor<'a> {
86
88
87
89
let ( message, label) = match & * name. as_str ( ) {
88
90
"C" => {
89
- conflicting_reprs += 1 ;
91
+ is_c = true ;
90
92
if target != Target :: Struct &&
91
93
target != Target :: Union &&
92
94
target != Target :: Enum {
@@ -108,7 +110,7 @@ impl<'a> CheckAttrVisitor<'a> {
108
110
}
109
111
}
110
112
"simd" => {
111
- conflicting_reprs += 1 ;
113
+ is_simd = true ;
112
114
if target != Target :: Struct {
113
115
( "attribute should be applied to struct" ,
114
116
"a struct" )
@@ -128,7 +130,7 @@ impl<'a> CheckAttrVisitor<'a> {
128
130
"i8" | "u8" | "i16" | "u16" |
129
131
"i32" | "u32" | "i64" | "u64" |
130
132
"isize" | "usize" => {
131
- conflicting_reprs += 1 ;
133
+ int_reprs += 1 ;
132
134
if target != Target :: Enum {
133
135
( "attribute should be applied to enum" ,
134
136
"an enum" )
@@ -142,7 +144,11 @@ impl<'a> CheckAttrVisitor<'a> {
142
144
. span_label ( item. span , format ! ( "not {}" , label) )
143
145
. emit ( ) ;
144
146
}
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) ) {
146
152
span_warn ! ( self . sess, attr. span, E0566 ,
147
153
"conflicting representation hints" ) ;
148
154
}
@@ -162,3 +168,17 @@ impl<'a> Visitor<'a> for CheckAttrVisitor<'a> {
162
168
pub fn check_crate ( sess : & Session , krate : & ast:: Crate ) {
163
169
visit:: walk_crate ( & mut CheckAttrVisitor { sess : sess } , krate) ;
164
170
}
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