@@ -3,14 +3,14 @@ use std::convert::identity;
33use rustc_ast as ast;
44use rustc_ast:: token:: DocFragmentKind ;
55use rustc_ast:: { AttrStyle , NodeId , Safety } ;
6- use rustc_errors:: DiagCtxtHandle ;
6+ use rustc_errors:: { DiagCtxtHandle , Diagnostic } ;
77use rustc_feature:: { AttributeTemplate , Features } ;
88use rustc_hir:: attrs:: AttributeKind ;
99use rustc_hir:: lints:: AttributeLint ;
1010use rustc_hir:: { AttrArgs , AttrItem , AttrPath , Attribute , HashIgnoredAttrId , Target } ;
1111use rustc_session:: Session ;
1212use rustc_session:: lint:: BuiltinLintDiag ;
13- use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
13+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span , Symbol , sym} ;
1414
1515use crate :: context:: { AcceptContext , FinalizeContext , SharedContext , Stage } ;
1616use crate :: parser:: { ArgParser , PathParser , RefPathParser } ;
@@ -23,7 +23,8 @@ pub struct AttributeParser<'sess, S: Stage = Late> {
2323 pub ( crate ) tools : Vec < Symbol > ,
2424 pub ( crate ) features : Option < & ' sess Features > ,
2525 pub ( crate ) sess : & ' sess Session ,
26- pub ( crate ) stage : S ,
26+ pub ( crate ) _stage : S ,
27+ pub ( crate ) should_emit : ShouldEmit ,
2728
2829 /// *Only* parse attributes with this symbol.
2930 ///
@@ -105,10 +106,10 @@ impl<'sess> AttributeParser<'sess, Early> {
105106 target_span : Span ,
106107 target_node_id : NodeId ,
107108 features : Option < & ' sess Features > ,
108- emit_errors : ShouldEmit ,
109+ should_emit : ShouldEmit ,
109110 ) -> Vec < Attribute > {
110111 let mut p =
111- Self { features, tools : Vec :: new ( ) , parse_only, sess, stage : Early { emit_errors } } ;
112+ Self { features, tools : Vec :: new ( ) , parse_only, sess, _stage : Early , should_emit } ;
112113 p. parse_attribute_list (
113114 attrs,
114115 target_span,
@@ -179,7 +180,7 @@ impl<'sess> AttributeParser<'sess, Early> {
179180 target_span : Span ,
180181 target_node_id : NodeId ,
181182 features : Option < & ' sess Features > ,
182- emit_errors : ShouldEmit ,
183+ should_emit : ShouldEmit ,
183184 args : & I ,
184185 parse_fn : fn ( cx : & mut AcceptContext < ' _ , ' _ , Early > , item : & I ) -> T ,
185186 template : & AttributeTemplate ,
@@ -189,7 +190,8 @@ impl<'sess> AttributeParser<'sess, Early> {
189190 tools : Vec :: new ( ) ,
190191 parse_only : None ,
191192 sess,
192- stage : Early { emit_errors } ,
193+ _stage : Early ,
194+ should_emit,
193195 } ;
194196 let mut emit_lint = |lint : AttributeLint < NodeId > | {
195197 sess. psess . buffer_lint (
@@ -232,8 +234,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
232234 features : & ' sess Features ,
233235 tools : Vec < Symbol > ,
234236 stage : S ,
237+ should_emit : ShouldEmit ,
235238 ) -> Self {
236- Self { features : Some ( features) , tools, parse_only : None , sess, stage }
239+ Self { features : Some ( features) , tools, parse_only : None , sess, _stage : stage, should_emit }
237240 }
238241
239242 pub ( crate ) fn sess ( & self ) -> & ' sess Session {
@@ -252,6 +255,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
252255 self . sess ( ) . dcx ( )
253256 }
254257
258+ pub ( crate ) fn emit_err ( & self , diag : impl for < ' x > Diagnostic < ' x > ) -> ErrorGuaranteed {
259+ self . should_emit . emit_err ( self . dcx ( ) . create_err ( diag) )
260+ }
261+
255262 /// Parse a list of attributes.
256263 ///
257264 /// `target_span` is the span of the thing this list of attributes is applied to,
@@ -263,14 +270,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
263270 target_id : S :: Id ,
264271 target : Target ,
265272 omit_doc : OmitDoc ,
266-
267273 lower_span : impl Copy + Fn ( Span ) -> Span ,
268274 mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
269275 ) -> Vec < Attribute > {
270276 let mut attributes = Vec :: new ( ) ;
271277 let mut attr_paths: Vec < RefPathParser < ' _ > > = Vec :: new ( ) ;
278+ let old_should_emit = self . should_emit ;
272279
273280 for attr in attrs {
281+ self . should_emit = old_should_emit; //FIXME ugly solution
282+
274283 // If we're only looking for a single attribute, skip all the ones we don't care about.
275284 if let Some ( expected) = self . parse_only {
276285 if !attr. has_name ( expected) {
@@ -305,6 +314,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
305314 attr_paths. push ( PathParser ( & n. item . path ) ) ;
306315 let attr_path = AttrPath :: from_ast ( & n. item . path , lower_span) ;
307316
317+ // Don't emit anything for trace attributes
318+ if attr. has_any_name ( & [ sym:: cfg_trace, sym:: cfg_attr_trace] ) {
319+ self . should_emit = ShouldEmit :: Nothing ;
320+ }
321+
308322 self . check_attribute_safety (
309323 & attr_path,
310324 lower_span ( n. item . span ( ) ) ,
@@ -321,7 +335,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
321335 & n. item . args ,
322336 & parts,
323337 & self . sess . psess ,
324- self . stage . should_emit ( ) ,
338+ self . should_emit ,
325339 ) else {
326340 continue ;
327341 } ;
@@ -374,9 +388,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
374388 } ;
375389
376390 ( accept. accept_fn ) ( & mut cx, & args) ;
377- if !matches ! ( cx. stage. should_emit( ) , ShouldEmit :: Nothing ) {
378- Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
379- }
391+ Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
380392 }
381393 } else {
382394 // If we're here, we must be compiling a tool attribute... Or someone
0 commit comments