@@ -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 (
@@ -206,7 +208,6 @@ impl<'sess> AttributeParser<'sess, Early> {
206208 safety,
207209 & mut emit_lint,
208210 target_node_id,
209- emit_errors,
210211 )
211212 }
212213 let mut cx: AcceptContext < ' _ , ' sess , Early > = AcceptContext {
@@ -233,8 +234,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
233234 features : & ' sess Features ,
234235 tools : Vec < Symbol > ,
235236 stage : S ,
237+ should_emit : ShouldEmit ,
236238 ) -> Self {
237- Self { features : Some ( features) , tools, parse_only : None , sess, stage }
239+ Self { features : Some ( features) , tools, parse_only : None , sess, _stage : stage, should_emit }
238240 }
239241
240242 pub ( crate ) fn sess ( & self ) -> & ' sess Session {
@@ -253,6 +255,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
253255 self . sess ( ) . dcx ( )
254256 }
255257
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+
256262 /// Parse a list of attributes.
257263 ///
258264 /// `target_span` is the span of the thing this list of attributes is applied to,
@@ -264,14 +270,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
264270 target_id : S :: Id ,
265271 target : Target ,
266272 omit_doc : OmitDoc ,
267-
268273 lower_span : impl Copy + Fn ( Span ) -> Span ,
269274 mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
270275 ) -> Vec < Attribute > {
271276 let mut attributes = Vec :: new ( ) ;
272277 let mut attr_paths: Vec < RefPathParser < ' _ > > = Vec :: new ( ) ;
278+ let old_should_emit = self . should_emit ;
273279
274280 for attr in attrs {
281+ self . should_emit = old_should_emit; //FIXME ugly solution
282+
275283 // If we're only looking for a single attribute, skip all the ones we don't care about.
276284 if let Some ( expected) = self . parse_only {
277285 if !attr. has_name ( expected) {
@@ -305,11 +313,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
305313 ast:: AttrKind :: Normal ( n) => {
306314 attr_paths. push ( PathParser ( & n. item . path ) ) ;
307315 let attr_path = AttrPath :: from_ast ( & n. item . path , lower_span) ;
308- let mut should_emit = self . stage . should_emit ( ) ;
309316
310317 // Don't emit anything for trace attributes
311318 if attr. has_any_name ( & [ sym:: cfg_trace, sym:: cfg_attr_trace] ) {
312- should_emit = ShouldEmit :: Nothing ;
319+ self . should_emit = ShouldEmit :: Nothing ;
313320 }
314321
315322 self . check_attribute_safety (
@@ -318,7 +325,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
318325 n. item . unsafety ,
319326 & mut emit_lint,
320327 target_id,
321- should_emit,
322328 ) ;
323329
324330 let parts =
@@ -329,7 +335,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
329335 & n. item . args ,
330336 & parts,
331337 & self . sess . psess ,
332- should_emit,
338+ self . should_emit ,
333339 ) else {
334340 continue ;
335341 } ;
@@ -382,9 +388,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
382388 } ;
383389
384390 ( accept. accept_fn ) ( & mut cx, & args) ;
385- if !matches ! ( should_emit, ShouldEmit :: Nothing ) {
386- Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
387- }
391+ Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
388392 }
389393 } else {
390394 // If we're here, we must be compiling a tool attribute... Or someone
0 commit comments