@@ -18,8 +18,7 @@ use ty::TyCtxt;
1818use syntax:: symbol:: Symbol ;
1919use syntax:: ast:: { Attribute , MetaItem , MetaItemKind } ;
2020use syntax_pos:: { Span , DUMMY_SP } ;
21- use hir;
22- use hir:: itemlikevisit:: ItemLikeVisitor ;
21+ use hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
2322use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
2423use errors:: DiagnosticId ;
2524
@@ -59,47 +58,44 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> {
5958 }
6059 }
6160
62- fn extract ( & self , attrs : & [ Attribute ] ) -> Vec < ( Symbol , Option < Symbol > , Span ) > {
61+ fn extract ( & self , attr : & Attribute ) -> Option < ( Symbol , Option < Symbol > , Span ) > {
6362 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+ _ => { }
8480 }
8581 }
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 ) ) ;
9389 }
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.
9890 }
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.
9995 }
10096 }
10197
102- features
98+ None
10399 }
104100
105101 fn collect_feature ( & mut self , feature : Symbol , since : Option < Symbol > , span : Span ) {
@@ -140,25 +136,17 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> {
140136 }
141137 }
142138 }
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- }
149139}
150140
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 )
158144 }
159145
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+ }
162150 }
163151}
164152
@@ -169,10 +157,6 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LibFeatures {
169157 collector. collect_feature ( feature, since, DUMMY_SP ) ;
170158 }
171159 }
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 ( ) ) ;
177161 collector. lib_features
178162}
0 commit comments