@@ -10,11 +10,11 @@ use rustc_ast::token::{self, Delimiter, MetaVarKind};
1010use rustc_ast:: tokenstream:: TokenStream ;
1111use rustc_ast:: { AttrArgs , DelimArgs , Expr , ExprKind , LitKind , MetaItemLit , NormalAttr , Path } ;
1212use rustc_ast_pretty:: pprust;
13- use rustc_errors:: PResult ;
13+ use rustc_errors:: { Diag , PResult } ;
1414use rustc_hir:: { self as hir, AttrPath } ;
1515use rustc_parse:: exp;
1616use rustc_parse:: parser:: { Parser , PathStyle , token_descr} ;
17- use rustc_session:: errors:: report_lit_error;
17+ use rustc_session:: errors:: { create_lit_error , report_lit_error} ;
1818use rustc_session:: parse:: ParseSess ;
1919use rustc_span:: { ErrorGuaranteed , Ident , Span , Symbol , sym} ;
2020use thin_vec:: ThinVec ;
@@ -379,22 +379,23 @@ struct MetaItemListParserContext<'a, 'sess> {
379379
380380impl < ' a , ' sess > MetaItemListParserContext < ' a , ' sess > {
381381 fn parse_unsuffixed_meta_item_lit ( & mut self ) -> PResult < ' sess , MetaItemLit > {
382- let uninterpolated_span = self . parser . token_uninterpolated_span ( ) ;
383- let Some ( token_lit) = self . parser . eat_token_lit ( ) else {
384- return self . parser . handle_missing_lit ( Parser :: mk_meta_item_lit_char) ;
385- } ;
382+ let Some ( token_lit) = self . parser . eat_token_lit ( ) else { return Err ( self . expected_lit ( ) ) } ;
383+ self . unsuffixed_meta_item_from_lit ( token_lit)
384+ }
386385
386+ fn unsuffixed_meta_item_from_lit (
387+ & mut self ,
388+ token_lit : token:: Lit ,
389+ ) -> PResult < ' sess , MetaItemLit > {
387390 let lit = match MetaItemLit :: from_token_lit ( token_lit, self . parser . prev_token . span ) {
388391 Ok ( lit) => lit,
389392 Err ( err) => {
390- let guar =
391- report_lit_error ( & self . parser . psess , err, token_lit, uninterpolated_span) ;
392- // Pack possible quotes and prefixes from the original literal into
393- // the error literal's symbol so they can be pretty-printed faithfully.
394- let suffixless_lit = token:: Lit :: new ( token_lit. kind , token_lit. symbol , None ) ;
395- let symbol = Symbol :: intern ( & suffixless_lit. to_string ( ) ) ;
396- let token_lit = token:: Lit :: new ( token:: Err ( guar) , symbol, token_lit. suffix ) ;
397- MetaItemLit :: from_token_lit ( token_lit, uninterpolated_span) . unwrap ( )
393+ return Err ( create_lit_error (
394+ & self . parser . psess ,
395+ err,
396+ token_lit,
397+ self . parser . prev_token_uninterpolated_span ( ) ,
398+ ) ) ;
398399 }
399400 } ;
400401
@@ -448,16 +449,28 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
448449 }
449450
450451 fn parse_meta_item_inner ( & mut self ) -> PResult < ' sess , MetaItemOrLitParser < ' static > > {
451- match self . parse_unsuffixed_meta_item_lit ( ) {
452- Ok ( lit) => return Ok ( MetaItemOrLitParser :: Lit ( lit) ) ,
453- Err ( err) => err. cancel ( ) , // we provide a better error below
454- }
455-
456- match self . parse_attr_item ( ) {
457- Ok ( mi) => return Ok ( MetaItemOrLitParser :: MetaItemParser ( mi) ) ,
458- Err ( err) => err. cancel ( ) , // we provide a better error below
452+ if let Some ( token_lit) = self . parser . eat_token_lit ( ) {
453+ // If a literal token is parsed, we commit to parsing a MetaItemLit for better errors
454+ Ok ( MetaItemOrLitParser :: Lit ( self . unsuffixed_meta_item_from_lit ( token_lit) ?) )
455+ } else {
456+ let prev_pros = self . parser . approx_token_stream_pos ( ) ;
457+ match self . parse_attr_item ( ) {
458+ Ok ( item) => Ok ( MetaItemOrLitParser :: MetaItemParser ( item) ) ,
459+ Err ( err) => {
460+ // If `parse_attr_item` made any progress, it likely has a more precise error we should prefer
461+ // If it didn't make progress we use the `expected_lit` from below
462+ if self . parser . approx_token_stream_pos ( ) != prev_pros {
463+ Err ( err)
464+ } else {
465+ err. cancel ( ) ;
466+ Err ( self . expected_lit ( ) )
467+ }
468+ }
469+ }
459470 }
471+ }
460472
473+ fn expected_lit ( & mut self ) -> Diag < ' sess > {
461474 let mut err = InvalidMetaItem {
462475 span : self . parser . token . span ,
463476 descr : token_descr ( & self . parser . token ) ,
@@ -492,7 +505,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
492505 self . parser . bump ( ) ;
493506 }
494507
495- Err ( self . parser . dcx ( ) . create_err ( err) )
508+ self . parser . dcx ( ) . create_err ( err)
496509 }
497510
498511 fn parse (
0 commit comments