@@ -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} ;
@@ -488,6 +488,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
488488 descr : token_descr ( & self . parser . token ) ,
489489 quote_ident_sugg : None ,
490490 remove_neg_sugg : None ,
491+ macro_call : None ,
491492 } ;
492493
493494 // Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and
@@ -496,20 +497,37 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
496497 if self . parser . prev_token == token:: Eq
497498 && let token:: Ident ( ..) = self . parser . token . kind
498499 {
499- let before = self . parser . token . span . shrink_to_lo ( ) ;
500- while let token:: Ident ( ..) = self . parser . token . kind {
501- self . parser . bump ( ) ;
500+ if self . parser . look_ahead ( 1 , |t| matches ! ( t. kind, token:: TokenKind :: Bang ) ) {
501+ let snapshot = self . parser . create_snapshot_for_diagnostic ( ) ;
502+ let stmt = self . parser . parse_stmt_without_recovery ( false , ForceCollect :: No , false ) ;
503+ match stmt {
504+ Ok ( Some ( stmt) ) => {
505+ // The user tried to write something like
506+ // `#[deprecated(note = concat!("a", "b"))]`.
507+ err. descr = format ! ( "macro {}" , err. descr) ;
508+ err. macro_call = Some ( stmt. span ) ;
509+ err. span = stmt. span ;
510+ }
511+ Ok ( None ) => { }
512+ Err ( err) => {
513+ err. cancel ( ) ;
514+ self . parser . restore_snapshot ( snapshot) ;
515+ }
516+ }
517+ } else {
518+ let before = self . parser . token . span . shrink_to_lo ( ) ;
519+ while let token:: Ident ( ..) = self . parser . token . kind {
520+ self . parser . bump ( ) ;
521+ }
522+ err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
523+ before,
524+ after : self . parser . prev_token . span . shrink_to_hi ( ) ,
525+ } ) ;
502526 }
503- err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
504- before,
505- after : self . parser . prev_token . span . shrink_to_hi ( ) ,
506- } ) ;
507527 }
508528
509529 if self . parser . token == token:: Minus
510- && self
511- . parser
512- . look_ahead ( 1 , |t| matches ! ( t. kind, rustc_ast:: token:: TokenKind :: Literal { .. } ) )
530+ && self . parser . look_ahead ( 1 , |t| matches ! ( t. kind, token:: TokenKind :: Literal { .. } ) )
513531 {
514532 err. remove_neg_sugg =
515533 Some ( InvalidMetaItemRemoveNegSugg { negative_sign : self . parser . token . span } ) ;
0 commit comments