@@ -93,70 +93,102 @@ struct CheckAttrVisitor<'tcx> {
93
93
impl CheckAttrVisitor < ' tcx > {
94
94
/// Checks any attribute.
95
95
fn check_attributes ( & self , item : & hir:: Item , target : Target ) {
96
- if target == Target :: Fn || target == Target :: Const {
97
- self . tcx . codegen_fn_attrs ( self . tcx . hir ( ) . local_def_id ( item. hir_id ) ) ;
98
- } else if let Some ( a) = item. attrs . iter ( ) . find ( |a| a. check_name ( sym:: target_feature) ) {
99
- self . tcx . sess . struct_span_err ( a. span , "attribute should be applied to a function" )
100
- . span_label ( item. span , "not a function" )
101
- . emit ( ) ;
102
- }
103
-
96
+ let mut is_valid = true ;
104
97
for attr in & item. attrs {
105
- if attr. check_name ( sym:: inline) {
98
+ is_valid &= if attr. check_name ( sym:: inline) {
106
99
self . check_inline ( attr, & item. span , target)
107
100
} else if attr. check_name ( sym:: non_exhaustive) {
108
101
self . check_non_exhaustive ( attr, item, target)
109
102
} else if attr. check_name ( sym:: marker) {
110
103
self . check_marker ( attr, item, target)
111
- }
104
+ } else if attr. check_name ( sym:: target_feature) {
105
+ self . check_target_feature ( attr, item, target)
106
+ } else {
107
+ true
108
+ } ;
109
+ }
110
+
111
+ if !is_valid {
112
+ return ;
113
+ }
114
+
115
+ if target == Target :: Fn {
116
+ self . tcx . codegen_fn_attrs ( self . tcx . hir ( ) . local_def_id ( item. hir_id ) ) ;
112
117
}
113
118
114
119
self . check_repr ( item, target) ;
115
120
self . check_used ( item, target) ;
116
121
}
117
122
118
- /// Checks if an `#[inline]` is applied to a function or a closure.
119
- fn check_inline ( & self , attr : & hir:: Attribute , span : & Span , target : Target ) {
123
+ /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid.
124
+ fn check_inline ( & self , attr : & hir:: Attribute , span : & Span , target : Target ) -> bool {
120
125
if target != Target :: Fn && target != Target :: Closure {
121
126
struct_span_err ! ( self . tcx. sess,
122
127
attr. span,
123
128
E0518 ,
124
129
"attribute should be applied to function or closure" )
125
130
. span_label ( * span, "not a function or closure" )
126
131
. emit ( ) ;
132
+ false
133
+ } else {
134
+ true
127
135
}
128
136
}
129
137
130
- /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid.
131
- fn check_non_exhaustive ( & self , attr : & hir:: Attribute , item : & hir:: Item , target : Target ) {
138
+ /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
139
+ fn check_non_exhaustive (
140
+ & self ,
141
+ attr : & hir:: Attribute ,
142
+ item : & hir:: Item ,
143
+ target : Target ,
144
+ ) -> bool {
132
145
match target {
133
- Target :: Struct | Target :: Enum => { /* Valid */ } ,
146
+ Target :: Struct | Target :: Enum => true ,
134
147
_ => {
135
148
struct_span_err ! ( self . tcx. sess,
136
149
attr. span,
137
150
E0701 ,
138
151
"attribute can only be applied to a struct or enum" )
139
152
. span_label ( item. span , "not a struct or enum" )
140
153
. emit ( ) ;
141
- return ;
154
+ false
142
155
}
143
156
}
144
157
}
145
158
146
- /// Checks if the `#[marker]` attribute on an `item` is valid.
147
- fn check_marker ( & self , attr : & hir:: Attribute , item : & hir:: Item , target : Target ) {
159
+ /// Checks if the `#[marker]` attribute on an `item` is valid. Returns `true` if valid.
160
+ fn check_marker ( & self , attr : & hir:: Attribute , item : & hir:: Item , target : Target ) -> bool {
148
161
match target {
149
- Target :: Trait => { /* Valid */ } ,
162
+ Target :: Trait => true ,
150
163
_ => {
151
164
self . tcx . sess
152
165
. struct_span_err ( attr. span , "attribute can only be applied to a trait" )
153
166
. span_label ( item. span , "not a trait" )
154
167
. emit ( ) ;
155
- return ;
168
+ false
156
169
}
157
170
}
158
171
}
159
172
173
+ /// Checks if the `#[target_feature]` attribute on `item` is valid. Returns `true` if valid.
174
+ fn check_target_feature (
175
+ & self ,
176
+ attr : & hir:: Attribute ,
177
+ item : & hir:: Item ,
178
+ target : Target ,
179
+ ) -> bool {
180
+ match target {
181
+ Target :: Fn => true ,
182
+ _ => {
183
+ self . tcx . sess
184
+ . struct_span_err ( attr. span , "attribute should be applied to a function" )
185
+ . span_label ( item. span , "not a function" )
186
+ . emit ( ) ;
187
+ false
188
+ } ,
189
+ }
190
+ }
191
+
160
192
/// Checks if the `#[repr]` attributes on `item` are valid.
161
193
fn check_repr ( & self , item : & hir:: Item , target : Target ) {
162
194
// Extract the names of all repr hints, e.g., [foo, bar, align] for:
0 commit comments