@@ -8,7 +8,9 @@ use std::fmt::{Debug, Display};
88
99use rustc_ast:: token:: { self , Delimiter , MetaVarKind } ;
1010use rustc_ast:: tokenstream:: TokenStream ;
11- use rustc_ast:: { AttrArgs , DelimArgs , Expr , ExprKind , LitKind , MetaItemLit , NormalAttr , Path } ;
11+ use rustc_ast:: {
12+ AttrArgs , DelimArgs , Expr , ExprKind , LitKind , MetaItemLit , NormalAttr , Path , StmtKind , UnOp ,
13+ } ;
1214use rustc_ast_pretty:: pprust;
1315use rustc_errors:: { Diag , PResult } ;
1416use rustc_hir:: { self as hir, AttrPath } ;
@@ -476,51 +478,55 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
476478 descr : token_descr ( & self . parser . token ) ,
477479 quote_ident_sugg : None ,
478480 remove_neg_sugg : None ,
479- macro_call : None ,
481+ label : None ,
480482 } ;
481483
484+ if let token:: OpenInvisible ( _) = self . parser . token . kind {
485+ // Do not attempt to suggest anything when encountered as part of a macro expansion.
486+ return self . parser . dcx ( ) . create_err ( err) ;
487+ }
488+
482489 // Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and
483490 // don't `uninterpolate` the token to avoid suggesting anything butchered or questionable
484491 // when macro metavariables are involved.
485- if self . parser . prev_token == token:: Eq
486- && let token:: Ident ( ..) = self . parser . token . kind
487- {
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) ;
492+ let snapshot = self . parser . create_snapshot_for_diagnostic ( ) ;
493+ let stmt = self . parser . parse_stmt_without_recovery ( false , ForceCollect :: No , false ) ;
494+ match stmt {
495+ Ok ( Some ( stmt) ) => {
496+ // The user tried to write something like
497+ // `#[deprecated(note = concat!("a", "b"))]`.
498+ err. descr = stmt. kind . descr ( ) . to_string ( ) ;
499+ err. label = Some ( stmt. span ) ;
500+ err. span = stmt. span ;
501+ if let StmtKind :: Expr ( expr) = & stmt. kind
502+ && let ExprKind :: Unary ( UnOp :: Neg , val) = & expr. kind
503+ && let ExprKind :: Lit ( _) = val. kind
504+ {
505+ err. remove_neg_sugg = Some ( InvalidMetaItemRemoveNegSugg {
506+ negative_sign : expr. span . until ( val. span ) ,
507+ } ) ;
508+ } else if let StmtKind :: Expr ( expr) = & stmt. kind
509+ && let ExprKind :: Path ( None , Path { segments, .. } ) = & expr. kind
510+ && segments. len ( ) == 1
511+ {
512+ while let token:: Ident ( ..) | token:: Literal ( _) | token:: Dot =
513+ self . parser . token . kind
514+ {
515+ // We've got a word, so we try to consume the rest of a potential sentence.
516+ // We include `.` to correctly handle things like `A sentence here.`.
517+ self . parser . bump ( ) ;
503518 }
519+ err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
520+ before : expr. span . shrink_to_lo ( ) ,
521+ after : self . parser . prev_token . span . shrink_to_hi ( ) ,
522+ } ) ;
504523 }
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- } ) ;
514524 }
515- }
516-
517- if self . parser . token == token:: Minus
518- && self . parser . look_ahead ( 1 , |t| matches ! ( t. kind, token:: TokenKind :: Literal { .. } ) )
519- {
520- err. remove_neg_sugg =
521- Some ( InvalidMetaItemRemoveNegSugg { negative_sign : self . parser . token . span } ) ;
522- self . parser . bump ( ) ;
523- self . parser . bump ( ) ;
525+ Ok ( None ) => { }
526+ Err ( e) => {
527+ e. cancel ( ) ;
528+ self . parser . restore_snapshot ( snapshot) ;
529+ }
524530 }
525531
526532 self . parser . dcx ( ) . create_err ( err)
0 commit comments