@@ -93,70 +93,102 @@ struct CheckAttrVisitor<'tcx> {
9393impl CheckAttrVisitor < ' tcx > {
9494 /// Checks any attribute.
9595 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 ;
10497 for attr in & item. attrs {
105- if attr. check_name ( sym:: inline) {
98+ is_valid &= if attr. check_name ( sym:: inline) {
10699 self . check_inline ( attr, & item. span , target)
107100 } else if attr. check_name ( sym:: non_exhaustive) {
108101 self . check_non_exhaustive ( attr, item, target)
109102 } else if attr. check_name ( sym:: marker) {
110103 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 ) ) ;
112117 }
113118
114119 self . check_repr ( item, target) ;
115120 self . check_used ( item, target) ;
116121 }
117122
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 {
120125 if target != Target :: Fn && target != Target :: Closure {
121126 struct_span_err ! ( self . tcx. sess,
122127 attr. span,
123128 E0518 ,
124129 "attribute should be applied to function or closure" )
125130 . span_label ( * span, "not a function or closure" )
126131 . emit ( ) ;
132+ false
133+ } else {
134+ true
127135 }
128136 }
129137
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 {
132145 match target {
133- Target :: Struct | Target :: Enum => { /* Valid */ } ,
146+ Target :: Struct | Target :: Enum => true ,
134147 _ => {
135148 struct_span_err ! ( self . tcx. sess,
136149 attr. span,
137150 E0701 ,
138151 "attribute can only be applied to a struct or enum" )
139152 . span_label ( item. span , "not a struct or enum" )
140153 . emit ( ) ;
141- return ;
154+ false
142155 }
143156 }
144157 }
145158
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 {
148161 match target {
149- Target :: Trait => { /* Valid */ } ,
162+ Target :: Trait => true ,
150163 _ => {
151164 self . tcx . sess
152165 . struct_span_err ( attr. span , "attribute can only be applied to a trait" )
153166 . span_label ( item. span , "not a trait" )
154167 . emit ( ) ;
155- return ;
168+ false
156169 }
157170 }
158171 }
159172
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+
160192 /// Checks if the `#[repr]` attributes on `item` are valid.
161193 fn check_repr ( & self , item : & hir:: Item , target : Target ) {
162194 // Extract the names of all repr hints, e.g., [foo, bar, align] for:
0 commit comments