1414//! conflicts between multiple such attributes attached to the same
1515//! item.
1616
17- use session :: Session ;
17+ use ty :: TyCtxt ;
1818
19- use syntax:: ast;
20- use syntax:: visit;
21- use syntax:: visit:: Visitor ;
19+ use hir;
20+ use hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
2221
2322#[ derive( Copy , Clone , PartialEq ) ]
2423enum Target {
@@ -30,45 +29,51 @@ enum Target {
3029}
3130
3231impl Target {
33- fn from_item ( item : & ast :: Item ) -> Target {
32+ fn from_item ( item : & hir :: Item ) -> Target {
3433 match item. node {
35- ast :: ItemKind :: Fn ( ..) => Target :: Fn ,
36- ast :: ItemKind :: Struct ( ..) => Target :: Struct ,
37- ast :: ItemKind :: Union ( ..) => Target :: Union ,
38- ast :: ItemKind :: Enum ( ..) => Target :: Enum ,
34+ hir :: ItemFn ( ..) => Target :: Fn ,
35+ hir :: ItemStruct ( ..) => Target :: Struct ,
36+ hir :: ItemUnion ( ..) => Target :: Union ,
37+ hir :: ItemEnum ( ..) => Target :: Enum ,
3938 _ => Target :: Other ,
4039 }
4140 }
4241}
4342
44- struct CheckAttrVisitor < ' a > {
45- sess : & ' a Session ,
43+ struct CheckAttrVisitor < ' a , ' tcx : ' a > {
44+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
4645}
4746
48- impl < ' a > CheckAttrVisitor < ' a > {
47+ impl < ' a , ' tcx > CheckAttrVisitor < ' a , ' tcx > {
4948 /// Check any attribute.
50- fn check_attributes ( & self , item : & ast:: Item , target : Target ) {
49+ fn check_attributes ( & self , item : & hir:: Item , target : Target ) {
50+ self . tcx . target_features_enabled ( self . tcx . hir . local_def_id ( item. id ) ) ;
51+
5152 for attr in & item. attrs {
5253 if let Some ( name) = attr. name ( ) {
5354 if name == "inline" {
5455 self . check_inline ( attr, item, target)
5556 }
5657 }
5758 }
59+
5860 self . check_repr ( item, target) ;
5961 }
6062
6163 /// Check if an `#[inline]` is applied to a function.
62- fn check_inline ( & self , attr : & ast :: Attribute , item : & ast :: Item , target : Target ) {
64+ fn check_inline ( & self , attr : & hir :: Attribute , item : & hir :: Item , target : Target ) {
6365 if target != Target :: Fn {
64- struct_span_err ! ( self . sess, attr. span, E0518 , "attribute should be applied to function" )
66+ struct_span_err ! ( self . tcx. sess,
67+ attr. span,
68+ E0518 ,
69+ "attribute should be applied to function" )
6570 . span_label ( item. span , "not a function" )
6671 . emit ( ) ;
6772 }
6873 }
6974
7075 /// Check if the `#[repr]` attributes on `item` are valid.
71- fn check_repr ( & self , item : & ast :: Item , target : Target ) {
76+ fn check_repr ( & self , item : & hir :: Item , target : Target ) {
7277 // Extract the names of all repr hints, e.g., [foo, bar, align] for:
7378 // ```
7479 // #[repr(foo)]
@@ -144,7 +149,7 @@ impl<'a> CheckAttrVisitor<'a> {
144149 }
145150 _ => continue ,
146151 } ;
147- struct_span_err ! ( self . sess, hint. span, E0517 ,
152+ struct_span_err ! ( self . tcx . sess, hint. span, E0517 ,
148153 "attribute should be applied to {}" , allowed_targets)
149154 . span_label ( item. span , format ! ( "not {} {}" , article, allowed_targets) )
150155 . emit ( ) ;
@@ -154,32 +159,37 @@ impl<'a> CheckAttrVisitor<'a> {
154159 if ( int_reprs > 1 )
155160 || ( is_simd && is_c)
156161 || ( int_reprs == 1 && is_c && is_c_like_enum ( item) ) {
157- // Just point at all repr hints. This is not ideal, but tracking precisely which ones
158- // are at fault is a huge hassle.
162+ // Just point at all repr hints. This is not ideal, but tracking
163+ // precisely which ones are at fault is a huge hassle.
159164 let spans: Vec < _ > = hints. iter ( ) . map ( |hint| hint. span ) . collect ( ) ;
160- span_warn ! ( self . sess, spans, E0566 ,
165+ span_warn ! ( self . tcx . sess, spans, E0566 ,
161166 "conflicting representation hints" ) ;
162167 }
163168 }
164169}
165170
166- impl < ' a > Visitor < ' a > for CheckAttrVisitor < ' a > {
167- fn visit_item ( & mut self , item : & ' a ast:: Item ) {
171+ impl < ' a , ' tcx > Visitor < ' tcx > for CheckAttrVisitor < ' a , ' tcx > {
172+ fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' tcx > {
173+ NestedVisitorMap :: None
174+ }
175+
176+ fn visit_item ( & mut self , item : & ' tcx hir:: Item ) {
168177 let target = Target :: from_item ( item) ;
169178 self . check_attributes ( item, target) ;
170- visit :: walk_item ( self , item) ;
179+ intravisit :: walk_item ( self , item) ;
171180 }
172181}
173182
174- pub fn check_crate ( sess : & Session , krate : & ast:: Crate ) {
175- visit:: walk_crate ( & mut CheckAttrVisitor { sess : sess } , krate) ;
183+ pub fn check_crate < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
184+ let mut checker = CheckAttrVisitor { tcx } ;
185+ tcx. hir . krate ( ) . visit_all_item_likes ( & mut checker. as_deep_visitor ( ) ) ;
176186}
177187
178- fn is_c_like_enum ( item : & ast :: Item ) -> bool {
179- if let ast :: ItemKind :: Enum ( ref def, _) = item. node {
188+ fn is_c_like_enum ( item : & hir :: Item ) -> bool {
189+ if let hir :: ItemEnum ( ref def, _) = item. node {
180190 for variant in & def. variants {
181191 match variant. node . data {
182- ast :: VariantData :: Unit ( _) => { /* continue */ }
192+ hir :: VariantData :: Unit ( _) => { /* continue */ }
183193 _ => { return false ; }
184194 }
185195 }
0 commit comments