@@ -3,15 +3,15 @@ use std::convert::identity;
33use rustc_ast as ast;
44use rustc_ast:: token:: DocFragmentKind ;
55use rustc_ast:: { AttrItemKind , AttrStyle , NodeId , Path , Safety } ;
6- use rustc_data_structures:: fx:: FxIndexMap ;
6+ use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
77use rustc_errors:: DiagCtxtHandle ;
88use rustc_feature:: { AttributeTemplate , Features } ;
99use rustc_hir:: attrs:: { AttrResolution , AttrResolutionKind , AttrResolved , AttributeKind } ;
1010use rustc_hir:: lints:: AttributeLintKind ;
1111use rustc_hir:: { AttrArgs , AttrItem , AttrPath , Attribute , HashIgnoredAttrId , Target } ;
1212use rustc_session:: Session ;
1313use rustc_session:: lint:: { BuiltinLintDiag , LintId } ;
14- use rustc_span:: { AttrId , DUMMY_SP , Span , Symbol , sym} ;
14+ use rustc_span:: { AttrId , DUMMY_SP , Ident , Span , Symbol , sym} ;
1515
1616use crate :: context:: { AcceptContext , FinalizeContext , FinalizeFn , SharedContext , Stage } ;
1717use crate :: early_parsed:: { EARLY_PARSED_ATTRIBUTES , EarlyParsedState } ;
@@ -34,7 +34,7 @@ struct LimitedParseResult {
3434/// Context created once, for example as part of the ast lowering
3535/// context, through which all attributes can be lowered.
3636pub struct AttributeParser < ' sess , S : Stage = Late > {
37- pub ( crate ) tools : Vec < Symbol > ,
37+ pub ( crate ) tools : Option < & ' sess FxIndexSet < Ident > > ,
3838 pub ( crate ) features : Option < & ' sess Features > ,
3939 pub ( crate ) sess : & ' sess Session ,
4040 pub ( crate ) stage : S ,
@@ -101,6 +101,7 @@ impl<'sess> AttributeParser<'sess, Early> {
101101 target_node_id,
102102 features,
103103 should_emit,
104+ None ,
104105 )
105106 . attributes ;
106107 assert ! ( parsed. len( ) <= 1 ) ;
@@ -127,6 +128,7 @@ impl<'sess> AttributeParser<'sess, Early> {
127128 target_node_id,
128129 features,
129130 should_emit,
131+ None ,
130132 )
131133 . attr_resolution_requests
132134 }
@@ -166,6 +168,7 @@ impl<'sess> AttributeParser<'sess, Early> {
166168 target_node_id : NodeId ,
167169 features : Option < & ' sess Features > ,
168170 emit_errors : ShouldEmit ,
171+ tools : Option < & ' sess FxIndexSet < Ident > > ,
169172 ) -> Vec < Attribute > {
170173 Self :: parse_limited_inner (
171174 sess,
@@ -176,10 +179,39 @@ impl<'sess> AttributeParser<'sess, Early> {
176179 target_node_id,
177180 features,
178181 emit_errors,
182+ tools,
179183 )
180184 . attributes
181185 }
182186
187+ /// This method provides the same functionality as [`parse_limited_all`](Self::parse_limited_all)
188+ /// except filtered, making sure that only allow-listed symbols are parsed.
189+ pub fn parse_limited_all_filtered (
190+ sess : & ' sess Session ,
191+ attrs : & [ ast:: Attribute ] ,
192+ filter : & [ Symbol ] ,
193+ target : Target ,
194+ target_span : Span ,
195+ target_node_id : NodeId ,
196+ features : Option < & ' sess Features > ,
197+ emit_errors : ShouldEmit ,
198+ tools : & ' sess FxIndexSet < Ident > ,
199+ ) -> Vec < Attribute > {
200+ let filtered =
201+ attrs. iter ( ) . filter ( |attr| attr. has_any_name ( filter) ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
202+ Self :: parse_limited_all (
203+ sess,
204+ & filtered,
205+ None ,
206+ target,
207+ target_span,
208+ target_node_id,
209+ features,
210+ emit_errors,
211+ Some ( tools) ,
212+ )
213+ }
214+
183215 fn parse_limited_inner (
184216 sess : & ' sess Session ,
185217 attrs : & [ ast:: Attribute ] ,
@@ -189,10 +221,11 @@ impl<'sess> AttributeParser<'sess, Early> {
189221 target_node_id : NodeId ,
190222 features : Option < & ' sess Features > ,
191223 emit_errors : ShouldEmit ,
224+ tools : Option < & ' sess FxIndexSet < Ident > > ,
192225 ) -> LimitedParseResult {
193226 let mut p = Self {
194227 features,
195- tools : Vec :: new ( ) ,
228+ tools,
196229 parse_only,
197230 sess,
198231 stage : Early { emit_errors } ,
@@ -285,7 +318,7 @@ impl<'sess> AttributeParser<'sess, Early> {
285318 ) -> T {
286319 let mut parser = Self {
287320 features,
288- tools : Vec :: new ( ) ,
321+ tools : None ,
289322 parse_only : None ,
290323 sess,
291324 stage : Early { emit_errors } ,
@@ -310,7 +343,7 @@ impl<'sess> AttributeParser<'sess, Early> {
310343 target,
311344 emit_lint : & mut emit_lint,
312345 } ,
313- attr_id : None ,
346+ attr_id : sess . psess . attr_id_generator . mk_attr_id ( ) ,
314347 attr_span,
315348 inner_span,
316349 attr_style,
@@ -326,13 +359,13 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
326359 pub fn new (
327360 sess : & ' sess Session ,
328361 features : & ' sess Features ,
329- tools : Vec < Symbol > ,
362+ tools : & ' sess FxIndexSet < Ident > ,
330363 attr_res_map : FxIndexMap < AttrId , Vec < AttrResolution < NodeId > > > ,
331364 stage : S ,
332365 ) -> Self {
333366 Self {
334367 features : Some ( features) ,
335- tools,
368+ tools : Some ( tools ) ,
336369 parse_only : None ,
337370 sess,
338371 stage,
@@ -521,7 +554,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
521554 target,
522555 emit_lint : & mut emit_lint,
523556 } ,
524- attr_id : Some ( attr. id ) ,
557+ attr_id : attr. id ,
525558 attr_span,
526559 inner_span : lower_span ( n. item . span ( ) ) ,
527560 attr_style : attr. style ,
@@ -554,11 +587,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
554587
555588 let attr = Attribute :: Unparsed ( Box :: new ( attr) ) ;
556589
557- if self . tools . contains ( & parts[ 0 ] )
558- // FIXME: this can be removed once #152369 has been merged.
559- // https://github.com/rust-lang/rust/pull/152369
560- || [ sym:: allow, sym:: deny, sym:: expect, sym:: forbid, sym:: warn]
561- . contains ( & parts[ 0 ] )
590+ if self
591+ . tools
592+ . is_some_and ( |tools| tools. iter ( ) . any ( |tool| tool. name == parts[ 0 ] ) )
562593 {
563594 attributes. push ( attr) ;
564595 } else {
0 commit comments