@@ -109,6 +109,8 @@ pub struct Argument<'a> {
109
109
pub struct FormatSpec < ' a > {
110
110
/// Optionally specified character to fill alignment with.
111
111
pub fill : Option < char > ,
112
+ /// Span of the optionally specified fill character.
113
+ pub fill_span : Option < InnerSpan > ,
112
114
/// Optionally specified alignment.
113
115
pub align : Alignment ,
114
116
/// The `+` or `-` flag.
@@ -264,7 +266,7 @@ impl<'a> Iterator for Parser<'a> {
264
266
Some ( String ( self . string ( pos + 1 ) ) )
265
267
} else {
266
268
let arg = self . argument ( lbrace_end) ;
267
- if let Some ( rbrace_pos) = self . must_consume ( '}' ) {
269
+ if let Some ( rbrace_pos) = self . consume_closing_brace ( & arg ) {
268
270
if self . is_source_literal {
269
271
let lbrace_byte_pos = self . to_span_index ( pos) ;
270
272
let rbrace_byte_pos = self . to_span_index ( rbrace_pos) ;
@@ -450,69 +452,51 @@ impl<'a> Parser<'a> {
450
452
451
453
/// Forces consumption of the specified character. If the character is not
452
454
/// found, an error is emitted.
453
- fn must_consume ( & mut self , c : char ) -> Option < usize > {
455
+ fn consume_closing_brace ( & mut self , arg : & Argument < ' _ > ) -> Option < usize > {
454
456
self . ws ( ) ;
455
457
456
- if let Some ( & ( pos, maybe) ) = self . cur . peek ( ) {
457
- if c == maybe {
458
+ let pos;
459
+ let description;
460
+
461
+ if let Some ( & ( peek_pos, maybe) ) = self . cur . peek ( ) {
462
+ if maybe == '}' {
458
463
self . cur . next ( ) ;
459
- Some ( pos)
460
- } else {
461
- let pos = self . to_span_index ( pos) ;
462
- let description = format ! ( "expected `'}}'`, found `{maybe:?}`" ) ;
463
- let label = "expected `}`" . to_owned ( ) ;
464
- let ( note, secondary_label) = if c == '}' {
465
- (
466
- Some (
467
- "if you intended to print `{`, you can escape it using `{{`" . to_owned ( ) ,
468
- ) ,
469
- self . last_opening_brace
470
- . map ( |sp| ( "because of this opening brace" . to_owned ( ) , sp) ) ,
471
- )
472
- } else {
473
- ( None , None )
474
- } ;
475
- self . errors . push ( ParseError {
476
- description,
477
- note,
478
- label,
479
- span : pos. to ( pos) ,
480
- secondary_label,
481
- should_be_replaced_with_positional_argument : false ,
482
- } ) ;
483
- None
464
+ return Some ( peek_pos) ;
484
465
}
466
+
467
+ pos = peek_pos;
468
+ description = format ! ( "expected `'}}'`, found `{maybe:?}`" ) ;
485
469
} else {
486
- let description = format ! ( "expected `{c:?} ` but string was terminated" ) ;
470
+ description = "expected `'}' ` but string was terminated" . to_owned ( ) ;
487
471
// point at closing `"`
488
- let pos = self . input . len ( ) - if self . append_newline { 1 } else { 0 } ;
489
- let pos = self . to_span_index ( pos) ;
490
- if c == '}' {
491
- let label = format ! ( "expected `{c:?}`" ) ;
492
- let ( note, secondary_label) = if c == '}' {
493
- (
494
- Some (
495
- "if you intended to print `{`, you can escape it using `{{`" . to_owned ( ) ,
496
- ) ,
497
- self . last_opening_brace
498
- . map ( |sp| ( "because of this opening brace" . to_owned ( ) , sp) ) ,
499
- )
500
- } else {
501
- ( None , None )
502
- } ;
503
- self . errors . push ( ParseError {
504
- description,
505
- note,
506
- label,
507
- span : pos. to ( pos) ,
508
- secondary_label,
509
- should_be_replaced_with_positional_argument : false ,
510
- } ) ;
511
- } else {
512
- self . err ( description, format ! ( "expected `{c:?}`" ) , pos. to ( pos) ) ;
513
- }
514
- None
472
+ pos = self . input . len ( ) - if self . append_newline { 1 } else { 0 } ;
515
473
}
474
+
475
+ let pos = self . to_span_index ( pos) ;
476
+
477
+ let label = "expected `'}'`" . to_owned ( ) ;
478
+ let ( note, secondary_label) = if arg. format . fill == Some ( '}' ) {
479
+ (
480
+ Some ( "the character `'}'` is interpreted as a fill character because of the `:` that precedes it" . to_owned ( ) ) ,
481
+ arg. format . fill_span . map ( |sp| ( "this is not interpreted as a formatting closing brace" . to_owned ( ) , sp) ) ,
482
+ )
483
+ } else {
484
+ (
485
+ Some ( "if you intended to print `{`, you can escape it using `{{`" . to_owned ( ) ) ,
486
+ self . last_opening_brace . map ( |sp| ( "because of this opening brace" . to_owned ( ) , sp) ) ,
487
+ )
488
+ } ;
489
+
490
+ self . errors . push ( ParseError {
491
+ description,
492
+ note,
493
+ label,
494
+ span : pos. to ( pos) ,
495
+ secondary_label,
496
+ should_be_replaced_with_positional_argument : false ,
497
+ } ) ;
498
+
499
+ None
516
500
}
517
501
518
502
/// Consumes all whitespace characters until the first non-whitespace character
@@ -608,6 +592,7 @@ impl<'a> Parser<'a> {
608
592
fn format ( & mut self ) -> FormatSpec < ' a > {
609
593
let mut spec = FormatSpec {
610
594
fill : None ,
595
+ fill_span : None ,
611
596
align : AlignUnknown ,
612
597
sign : None ,
613
598
alternate : false ,
@@ -625,9 +610,10 @@ impl<'a> Parser<'a> {
625
610
}
626
611
627
612
// fill character
628
- if let Some ( & ( _ , c) ) = self . cur . peek ( ) {
613
+ if let Some ( & ( idx , c) ) = self . cur . peek ( ) {
629
614
if let Some ( ( _, '>' | '<' | '^' ) ) = self . cur . clone ( ) . nth ( 1 ) {
630
615
spec. fill = Some ( c) ;
616
+ spec. fill_span = Some ( self . span ( idx, idx + 1 ) ) ;
631
617
self . cur . next ( ) ;
632
618
}
633
619
}
@@ -722,6 +708,7 @@ impl<'a> Parser<'a> {
722
708
fn inline_asm ( & mut self ) -> FormatSpec < ' a > {
723
709
let mut spec = FormatSpec {
724
710
fill : None ,
711
+ fill_span : None ,
725
712
align : AlignUnknown ,
726
713
sign : None ,
727
714
alternate : false ,
0 commit comments