@@ -8,7 +8,7 @@ use std::fmt::{Debug, Display};
88
99use rustc_ast:: token:: { self , Delimiter , MetaVarKind } ;
1010use rustc_ast:: tokenstream:: TokenStream ;
11- use rustc_ast:: { AttrArgs , Expr , ExprKind , LitKind , MetaItemLit , NormalAttr , Path } ;
11+ use rustc_ast:: { AttrArgs , Expr , ExprKind , LitKind , MetaItemLit , NormalAttr , Path , StmtKind , UnOp } ;
1212use rustc_ast_pretty:: pprust;
1313use rustc_errors:: { Diag , PResult } ;
1414use rustc_hir:: { self as hir, AttrPath } ;
@@ -488,51 +488,55 @@ 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 ,
491+ label : None ,
492492 } ;
493493
494+ if let token:: OpenInvisible ( _) = self . parser . token . kind {
495+ // Do not attempt to suggest anything when encountered as part of a macro expansion.
496+ return self . parser . dcx ( ) . create_err ( err) ;
497+ }
498+
494499 // Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and
495500 // don't `uninterpolate` the token to avoid suggesting anything butchered or questionable
496501 // when macro metavariables are involved.
497- if self . parser . prev_token == token:: Eq
498- && let token:: Ident ( ..) = self . parser . token . kind
499- {
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) ;
502+ let snapshot = self . parser . create_snapshot_for_diagnostic ( ) ;
503+ let stmt = self . parser . parse_stmt_without_recovery ( false , ForceCollect :: No , false ) ;
504+ match stmt {
505+ Ok ( Some ( stmt) ) => {
506+ // The user tried to write something like
507+ // `#[deprecated(note = concat!("a", "b"))]`.
508+ err. descr = stmt. kind . descr ( ) . to_string ( ) ;
509+ err. label = Some ( stmt. span ) ;
510+ err. span = stmt. span ;
511+ if let StmtKind :: Expr ( expr) = & stmt. kind
512+ && let ExprKind :: Unary ( UnOp :: Neg , val) = & expr. kind
513+ && let ExprKind :: Lit ( _) = val. kind
514+ {
515+ err. remove_neg_sugg = Some ( InvalidMetaItemRemoveNegSugg {
516+ negative_sign : expr. span . until ( val. span ) ,
517+ } ) ;
518+ } else if let StmtKind :: Expr ( expr) = & stmt. kind
519+ && let ExprKind :: Path ( None , Path { segments, .. } ) = & expr. kind
520+ && segments. len ( ) == 1
521+ {
522+ while let token:: Ident ( ..) | token:: Literal ( _) | token:: Dot =
523+ self . parser . token . kind
524+ {
525+ // We've got a word, so we try to consume the rest of a potential sentence.
526+ // We include `.` to correctly handle things like `A sentence here.`.
527+ self . parser . bump ( ) ;
515528 }
529+ err. quote_ident_sugg = Some ( InvalidMetaItemQuoteIdentSugg {
530+ before : expr. span . shrink_to_lo ( ) ,
531+ after : self . parser . prev_token . span . shrink_to_hi ( ) ,
532+ } ) ;
516533 }
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- } ) ;
526534 }
527- }
528-
529- if self . parser . token == token:: Minus
530- && self . parser . look_ahead ( 1 , |t| matches ! ( t. kind, token:: TokenKind :: Literal { .. } ) )
531- {
532- err. remove_neg_sugg =
533- Some ( InvalidMetaItemRemoveNegSugg { negative_sign : self . parser . token . span } ) ;
534- self . parser . bump ( ) ;
535- self . parser . bump ( ) ;
535+ Ok ( None ) => { }
536+ Err ( e) => {
537+ e. cancel ( ) ;
538+ self . parser . restore_snapshot ( snapshot) ;
539+ }
536540 }
537541
538542 self . parser . dcx ( ) . create_err ( err)
0 commit comments