@@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust;
1313use rustc_errors:: { Diag , PResult } ;
1414use rustc_hir:: { self as hir, AttrPath } ;
1515use rustc_parse:: exp;
16- use rustc_parse:: parser:: { Parser , PathStyle , token_descr} ;
16+ use rustc_parse:: parser:: { ForceCollect , Parser , PathStyle , token_descr} ;
1717use rustc_session:: errors:: { create_lit_error, report_lit_error} ;
1818use rustc_session:: parse:: ParseSess ;
1919use rustc_span:: { ErrorGuaranteed , Ident , Span , Symbol , sym} ;
@@ -476,6 +476,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
476476 descr : token_descr ( & self . parser . token ) ,
477477 quote_ident_sugg : None ,
478478 remove_neg_sugg : None ,
479+ macro_call : None ,
479480 } ;
480481
481482 // 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> {
484485 if self . parser . prev_token == token:: Eq
485486 && let token:: Ident ( ..) = self . parser . token . kind
486487 {
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+ } ) ;
490514 }
491- err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
492- before,
493- after : self . parser . prev_token . span . shrink_to_hi ( ) ,
494- } ) ;
495515 }
496516
497517 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 { .. } ) )
501519 {
502520 err. remove_neg_sugg =
503521 Some ( InvalidMetaItemRemoveNegSugg { negative_sign : self . parser . token . span } ) ;
0 commit comments