@@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust;
13
13
use rustc_errors:: { Diag , PResult } ;
14
14
use rustc_hir:: { self as hir, AttrPath } ;
15
15
use rustc_parse:: exp;
16
- use rustc_parse:: parser:: { Parser , PathStyle , token_descr} ;
16
+ use rustc_parse:: parser:: { ForceCollect , Parser , PathStyle , token_descr} ;
17
17
use rustc_session:: errors:: { create_lit_error, report_lit_error} ;
18
18
use rustc_session:: parse:: ParseSess ;
19
19
use rustc_span:: { ErrorGuaranteed , Ident , Span , Symbol , sym} ;
@@ -476,6 +476,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
476
476
descr : token_descr ( & self . parser . token ) ,
477
477
quote_ident_sugg : None ,
478
478
remove_neg_sugg : None ,
479
+ macro_call : None ,
479
480
} ;
480
481
481
482
// Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and
@@ -484,20 +485,37 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
484
485
if self . parser . prev_token == token:: Eq
485
486
&& let token:: Ident ( ..) = self . parser . token . kind
486
487
{
487
- let before = self . parser . token . span . shrink_to_lo ( ) ;
488
- while let token:: Ident ( ..) = self . parser . token . kind {
489
- self . parser . bump ( ) ;
488
+ if self . parser . look_ahead ( 1 , |t| matches ! ( t. kind, token:: TokenKind :: Bang ) ) {
489
+ let snapshot = self . parser . create_snapshot_for_diagnostic ( ) ;
490
+ let stmt = self . parser . parse_stmt_without_recovery ( false , ForceCollect :: No , false ) ;
491
+ match stmt {
492
+ Ok ( Some ( stmt) ) => {
493
+ // The user tried to write something like
494
+ // `#[deprecated(note = concat!("a", "b"))]`.
495
+ err. descr = format ! ( "macro {}" , err. descr) ;
496
+ err. macro_call = Some ( stmt. span ) ;
497
+ err. span = stmt. span ;
498
+ }
499
+ Ok ( None ) => { }
500
+ Err ( err) => {
501
+ err. cancel ( ) ;
502
+ self . parser . restore_snapshot ( snapshot) ;
503
+ }
504
+ }
505
+ } else {
506
+ let before = self . parser . token . span . shrink_to_lo ( ) ;
507
+ while let token:: Ident ( ..) = self . parser . token . kind {
508
+ self . parser . bump ( ) ;
509
+ }
510
+ err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
511
+ before,
512
+ after : self . parser . prev_token . span . shrink_to_hi ( ) ,
513
+ } ) ;
490
514
}
491
- err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
492
- before,
493
- after : self . parser . prev_token . span . shrink_to_hi ( ) ,
494
- } ) ;
495
515
}
496
516
497
517
if self . parser . token == token:: Minus
498
- && self
499
- . parser
500
- . look_ahead ( 1 , |t| matches ! ( t. kind, rustc_ast:: token:: TokenKind :: Literal { .. } ) )
518
+ && self . parser . look_ahead ( 1 , |t| matches ! ( t. kind, token:: TokenKind :: Literal { .. } ) )
501
519
{
502
520
err. remove_neg_sugg =
503
521
Some ( InvalidMetaItemRemoveNegSugg { negative_sign : self . parser . token . span } ) ;
0 commit comments