@@ -18,8 +18,7 @@ use ty::TyCtxt;
18
18
use syntax:: symbol:: Symbol ;
19
19
use syntax:: ast:: { Attribute , MetaItem , MetaItemKind } ;
20
20
use syntax_pos:: { Span , DUMMY_SP } ;
21
- use hir;
22
- use hir:: itemlikevisit:: ItemLikeVisitor ;
21
+ use hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
23
22
use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
24
23
use errors:: DiagnosticId ;
25
24
@@ -59,47 +58,44 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> {
59
58
}
60
59
}
61
60
62
- fn extract ( & self , attrs : & [ Attribute ] ) -> Vec < ( Symbol , Option < Symbol > , Span ) > {
61
+ fn extract ( & self , attr : & Attribute ) -> Option < ( Symbol , Option < Symbol > , Span ) > {
63
62
let stab_attrs = vec ! [ "stable" , "unstable" , "rustc_const_unstable" ] ;
64
- let mut features = vec ! [ ] ;
65
-
66
- for attr in attrs {
67
- // Find a stability attribute (i.e. `#[stable (..)]`, `#[unstable (..)]`,
68
- // `#[rustc_const_unstable (..)]`).
69
- if let Some ( stab_attr) = stab_attrs. iter ( ) . find ( |stab_attr| {
70
- attr. check_name ( stab_attr)
71
- } ) {
72
- let meta_item = attr. meta ( ) ;
73
- if let Some ( MetaItem { node : MetaItemKind :: List ( ref metas) , .. } ) = meta_item {
74
- let mut feature = None ;
75
- let mut since = None ;
76
- for meta in metas {
77
- if let Some ( mi) = meta. meta_item ( ) {
78
- // Find the `feature = ".."` meta-item.
79
- match ( & * mi. name ( ) . as_str ( ) , mi. value_str ( ) ) {
80
- ( "feature" , val) => feature = val,
81
- ( "since" , val) => since = val,
82
- _ => { }
83
- }
63
+
64
+ // Find a stability attribute (i.e. `#[stable (..)]`, `#[unstable (..)]`,
65
+ // `#[rustc_const_unstable (..)]`).
66
+ if let Some ( stab_attr) = stab_attrs. iter ( ) . find ( |stab_attr| {
67
+ attr. check_name ( stab_attr)
68
+ } ) {
69
+ let meta_item = attr. meta ( ) ;
70
+ if let Some ( MetaItem { node : MetaItemKind :: List ( ref metas) , .. } ) = meta_item {
71
+ let mut feature = None ;
72
+ let mut since = None ;
73
+ for meta in metas {
74
+ if let Some ( mi) = meta. meta_item ( ) {
75
+ // Find the `feature = ".."` meta-item.
76
+ match ( & * mi. name ( ) . as_str ( ) , mi. value_str ( ) ) {
77
+ ( "feature" , val) => feature = val,
78
+ ( "since" , val) => since = val,
79
+ _ => { }
84
80
}
85
81
}
86
- if let Some ( feature ) = feature {
87
- // This additional check for stability is to make sure we
88
- // don't emit additional, irrelevant errors for malformed
89
- // attributes.
90
- if * stab_attr != "stable" || since . is_some ( ) {
91
- features . push ( ( feature , since, attr . span ) ) ;
92
- }
82
+ }
83
+ if let Some ( feature ) = feature {
84
+ // This additional check for stability is to make sure we
85
+ // don't emit additional, irrelevant errors for malformed
86
+ // attributes.
87
+ if * stab_attr != "stable" || since. is_some ( ) {
88
+ return Some ( ( feature , since , attr . span ) ) ;
93
89
}
94
- // We need to iterate over the other attributes, because
95
- // `rustc_const_unstable` is not mutually exclusive with
96
- // the other stability attributes, so we can't just `break`
97
- // here.
98
90
}
91
+ // We need to iterate over the other attributes, because
92
+ // `rustc_const_unstable` is not mutually exclusive with
93
+ // the other stability attributes, so we can't just `break`
94
+ // here.
99
95
}
100
96
}
101
97
102
- features
98
+ None
103
99
}
104
100
105
101
fn collect_feature ( & mut self , feature : Symbol , since : Option < Symbol > , span : Span ) {
@@ -140,25 +136,17 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> {
140
136
}
141
137
}
142
138
}
143
-
144
- fn collect_from_attrs ( & mut self , attrs : & [ Attribute ] ) {
145
- for ( feature, stable, span) in self . extract ( attrs) {
146
- self . collect_feature ( feature, stable, span) ;
147
- }
148
- }
149
139
}
150
140
151
- impl < ' a , ' v , ' tcx > ItemLikeVisitor < ' v > for LibFeatureCollector < ' a , ' tcx > {
152
- fn visit_item ( & mut self , item : & hir:: Item ) {
153
- self . collect_from_attrs ( & item. attrs ) ;
154
- }
155
-
156
- fn visit_trait_item ( & mut self , trait_item : & hir:: TraitItem ) {
157
- self . collect_from_attrs ( & trait_item. attrs ) ;
141
+ impl < ' a , ' tcx > Visitor < ' tcx > for LibFeatureCollector < ' a , ' tcx > {
142
+ fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' tcx > {
143
+ NestedVisitorMap :: All ( & self . tcx . hir )
158
144
}
159
145
160
- fn visit_impl_item ( & mut self , impl_item : & hir:: ImplItem ) {
161
- self . collect_from_attrs ( & impl_item. attrs ) ;
146
+ fn visit_attribute ( & mut self , attr : & ' tcx Attribute ) {
147
+ if let Some ( ( feature, stable, span) ) = self . extract ( attr) {
148
+ self . collect_feature ( feature, stable, span) ;
149
+ }
162
150
}
163
151
}
164
152
@@ -169,10 +157,6 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LibFeatures {
169
157
collector. collect_feature ( feature, since, DUMMY_SP ) ;
170
158
}
171
159
}
172
- collector. collect_from_attrs ( & tcx. hir . krate ( ) . attrs ) ;
173
- tcx. hir . krate ( ) . visit_all_item_likes ( & mut collector) ;
174
- for exported_macro in & tcx. hir . krate ( ) . exported_macros {
175
- collector. collect_from_attrs ( & exported_macro. attrs ) ;
176
- }
160
+ intravisit:: walk_crate ( & mut collector, tcx. hir . krate ( ) ) ;
177
161
collector. lib_features
178
162
}
0 commit comments