14
14
//! conflicts between multiple such attributes attached to the same
15
15
//! item.
16
16
17
- use session :: Session ;
17
+ use ty :: TyCtxt ;
18
18
19
- use syntax:: ast;
20
- use syntax:: visit;
21
- use syntax:: visit:: Visitor ;
19
+ use hir;
20
+ use hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
22
21
23
22
#[ derive( Copy , Clone , PartialEq ) ]
24
23
enum Target {
@@ -30,45 +29,51 @@ enum Target {
30
29
}
31
30
32
31
impl Target {
33
- fn from_item ( item : & ast :: Item ) -> Target {
32
+ fn from_item ( item : & hir :: Item ) -> Target {
34
33
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 ,
39
38
_ => Target :: Other ,
40
39
}
41
40
}
42
41
}
43
42
44
- struct CheckAttrVisitor < ' a > {
45
- sess : & ' a Session ,
43
+ struct CheckAttrVisitor < ' a , ' tcx : ' a > {
44
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
46
45
}
47
46
48
- impl < ' a > CheckAttrVisitor < ' a > {
47
+ impl < ' a , ' tcx > CheckAttrVisitor < ' a , ' tcx > {
49
48
/// 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
+
51
52
for attr in & item. attrs {
52
53
if let Some ( name) = attr. name ( ) {
53
54
if name == "inline" {
54
55
self . check_inline ( attr, item, target)
55
56
}
56
57
}
57
58
}
59
+
58
60
self . check_repr ( item, target) ;
59
61
}
60
62
61
63
/// 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 ) {
63
65
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" )
65
70
. span_label ( item. span , "not a function" )
66
71
. emit ( ) ;
67
72
}
68
73
}
69
74
70
75
/// 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 ) {
72
77
// Extract the names of all repr hints, e.g., [foo, bar, align] for:
73
78
// ```
74
79
// #[repr(foo)]
@@ -144,7 +149,7 @@ impl<'a> CheckAttrVisitor<'a> {
144
149
}
145
150
_ => continue ,
146
151
} ;
147
- struct_span_err ! ( self . sess, hint. span, E0517 ,
152
+ struct_span_err ! ( self . tcx . sess, hint. span, E0517 ,
148
153
"attribute should be applied to {}" , allowed_targets)
149
154
. span_label ( item. span , format ! ( "not {} {}" , article, allowed_targets) )
150
155
. emit ( ) ;
@@ -154,32 +159,37 @@ impl<'a> CheckAttrVisitor<'a> {
154
159
if ( int_reprs > 1 )
155
160
|| ( is_simd && is_c)
156
161
|| ( 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.
159
164
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 ,
161
166
"conflicting representation hints" ) ;
162
167
}
163
168
}
164
169
}
165
170
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 ) {
168
177
let target = Target :: from_item ( item) ;
169
178
self . check_attributes ( item, target) ;
170
- visit :: walk_item ( self , item) ;
179
+ intravisit :: walk_item ( self , item) ;
171
180
}
172
181
}
173
182
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 ( ) ) ;
176
186
}
177
187
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 {
180
190
for variant in & def. variants {
181
191
match variant. node . data {
182
- ast :: VariantData :: Unit ( _) => { /* continue */ }
192
+ hir :: VariantData :: Unit ( _) => { /* continue */ }
183
193
_ => { return false ; }
184
194
}
185
195
}
0 commit comments