11use std:: convert:: identity;
2+ use std:: marker:: PhantomData ;
23
34use rustc_ast as ast;
45use rustc_ast:: token:: DocFragmentKind ;
56use rustc_ast:: { AttrItemKind , AttrStyle , CRATE_NODE_ID , NodeId , Safety } ;
67use rustc_data_structures:: sync:: { DynSend , DynSync } ;
7- use rustc_errors:: { Diag , DiagCtxtHandle , Level , MultiSpan } ;
8+ use rustc_errors:: { Diag , DiagCtxtHandle , Diagnostic , Level , MultiSpan } ;
89use rustc_feature:: { AttributeTemplate , Features } ;
910use rustc_hir:: attrs:: AttributeKind ;
1011use rustc_hir:: lints:: AttributeLintKind ;
1112use rustc_hir:: { AttrArgs , AttrItem , AttrPath , Attribute , HashIgnoredAttrId , Target } ;
1213use rustc_session:: Session ;
1314use rustc_session:: lint:: LintId ;
14- use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
15+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span , Symbol , sym} ;
1516
1617use crate :: attributes:: AttributeSafety ;
1718use crate :: context:: { AcceptContext , FinalizeContext , FinalizeFn , SharedContext , Stage } ;
@@ -35,7 +36,8 @@ pub struct AttributeParser<'sess, S: Stage = Late> {
3536 pub ( crate ) tools : Vec < Symbol > ,
3637 pub ( crate ) features : Option < & ' sess Features > ,
3738 pub ( crate ) sess : & ' sess Session ,
38- pub ( crate ) stage : S ,
39+ pub ( crate ) stage : PhantomData < S > ,
40+ pub ( crate ) should_emit : ShouldEmit ,
3941
4042 /// *Only* parse attributes with this symbol.
4143 ///
@@ -117,10 +119,10 @@ impl<'sess> AttributeParser<'sess, Early> {
117119 target_span : Span ,
118120 target_node_id : NodeId ,
119121 features : Option < & ' sess Features > ,
120- emit_errors : ShouldEmit ,
122+ should_emit : ShouldEmit ,
121123 ) -> Vec < Attribute > {
122124 let mut p =
123- Self { features, tools : Vec :: new ( ) , parse_only, sess, stage : Early { emit_errors } } ;
125+ Self { features, tools : Vec :: new ( ) , parse_only, sess, stage : PhantomData , should_emit } ;
124126 p. parse_attribute_list (
125127 attrs,
126128 target_span,
@@ -202,7 +204,7 @@ impl<'sess> AttributeParser<'sess, Early> {
202204 target_node_id : NodeId ,
203205 target : Target ,
204206 features : Option < & ' sess Features > ,
205- emit_errors : ShouldEmit ,
207+ should_emit : ShouldEmit ,
206208 args : & I ,
207209 parse_fn : fn ( cx : & mut AcceptContext < ' _ , ' _ , Early > , item : & I ) -> T ,
208210 template : & AttributeTemplate ,
@@ -212,7 +214,8 @@ impl<'sess> AttributeParser<'sess, Early> {
212214 tools : Vec :: new ( ) ,
213215 parse_only : None ,
214216 sess,
215- stage : Early { emit_errors } ,
217+ stage : PhantomData ,
218+ should_emit,
216219 } ;
217220 let mut emit_lint = |lint_id : LintId , span : MultiSpan , kind : EmitAttribute | match kind {
218221 EmitAttribute :: Static ( kind) => {
@@ -254,9 +257,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
254257 sess : & ' sess Session ,
255258 features : & ' sess Features ,
256259 tools : Vec < Symbol > ,
257- stage : S ,
260+ should_emit : ShouldEmit ,
258261 ) -> Self {
259- Self { features : Some ( features) , tools, parse_only : None , sess, stage }
262+ Self {
263+ features : Some ( features) ,
264+ tools,
265+ parse_only : None ,
266+ sess,
267+ should_emit,
268+ stage : PhantomData ,
269+ }
260270 }
261271
262272 pub ( crate ) fn sess ( & self ) -> & ' sess Session {
@@ -275,6 +285,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
275285 self . sess ( ) . dcx ( )
276286 }
277287
288+ pub ( crate ) fn emit_err ( & self , diag : impl for < ' x > Diagnostic < ' x > ) -> ErrorGuaranteed {
289+ self . should_emit . emit_err ( self . sess . dcx ( ) . create_err ( diag) )
290+ }
291+
278292 /// Parse a list of attributes.
279293 ///
280294 /// `target_span` is the span of the thing this list of attributes is applied to,
@@ -360,7 +374,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
360374 args,
361375 & parts,
362376 & self . sess . psess ,
363- self . stage . should_emit ( ) ,
377+ self . should_emit ,
364378 AllowExprMetavar :: No ,
365379 ) else {
366380 continue ;
@@ -415,7 +429,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
415429 ( accept. accept_fn ) ( & mut cx, & args) ;
416430 finalizers. push ( & accept. finalizer ) ;
417431
418- if !matches ! ( cx. stage . should_emit( ) , ShouldEmit :: Nothing ) {
432+ if !matches ! ( cx. should_emit, ShouldEmit :: Nothing ) {
419433 Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
420434 }
421435 } else {
@@ -436,7 +450,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
436450 & mut emit_lint,
437451 ) ;
438452
439- if !matches ! ( self . stage . should_emit( ) , ShouldEmit :: Nothing )
453+ if !matches ! ( self . should_emit, ShouldEmit :: Nothing )
440454 && target == Target :: Crate
441455 {
442456 self . check_invalid_crate_level_attr_item ( & attr, n. item . span ( ) ) ;
@@ -469,9 +483,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
469483 }
470484 }
471485
472- if !matches ! ( self . stage. should_emit( ) , ShouldEmit :: Nothing )
473- && target == Target :: WherePredicate
474- {
486+ if !matches ! ( self . should_emit, ShouldEmit :: Nothing ) && target == Target :: WherePredicate {
475487 self . check_invalid_where_predicate_attrs ( attributes. iter ( ) . chain ( & dropped_attributes) ) ;
476488 }
477489
0 commit comments