@@ -10,11 +10,11 @@ use rustc_ast::token::{self, Delimiter, MetaVarKind};
10
10
use rustc_ast:: tokenstream:: TokenStream ;
11
11
use rustc_ast:: { AttrArgs , DelimArgs , Expr , ExprKind , LitKind , MetaItemLit , NormalAttr , Path } ;
12
12
use rustc_ast_pretty:: pprust;
13
- use rustc_errors:: PResult ;
13
+ use rustc_errors:: { Diag , PResult } ;
14
14
use rustc_hir:: { self as hir, AttrPath } ;
15
15
use rustc_parse:: exp;
16
16
use 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} ;
18
18
use rustc_session:: parse:: ParseSess ;
19
19
use rustc_span:: { ErrorGuaranteed , Ident , Span , Symbol , sym} ;
20
20
use thin_vec:: ThinVec ;
@@ -379,22 +379,23 @@ struct MetaItemListParserContext<'a, 'sess> {
379
379
380
380
impl < ' a , ' sess > MetaItemListParserContext < ' a , ' sess > {
381
381
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
+ }
386
385
386
+ fn unsuffixed_meta_item_from_lit (
387
+ & mut self ,
388
+ token_lit : token:: Lit ,
389
+ ) -> PResult < ' sess , MetaItemLit > {
387
390
let lit = match MetaItemLit :: from_token_lit ( token_lit, self . parser . prev_token . span ) {
388
391
Ok ( lit) => lit,
389
392
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
+ ) ) ;
398
399
}
399
400
} ;
400
401
@@ -448,16 +449,28 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
448
449
}
449
450
450
451
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
+ }
459
470
}
471
+ }
460
472
473
+ fn expected_lit ( & mut self ) -> Diag < ' sess > {
461
474
let mut err = InvalidMetaItem {
462
475
span : self . parser . token . span ,
463
476
descr : token_descr ( & self . parser . token ) ,
@@ -492,7 +505,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
492
505
self . parser . bump ( ) ;
493
506
}
494
507
495
- Err ( self . parser . dcx ( ) . create_err ( err) )
508
+ self . parser . dcx ( ) . create_err ( err)
496
509
}
497
510
498
511
fn parse (
0 commit comments