@@ -5428,87 +5428,76 @@ impl<'a> Parser<'a> {
5428
5428
//
5429
5429
// In doing this, we have managed to work out how many unmatched leading left angle
5430
5430
// brackets there are, but we cannot recover as the unmatched angle brackets have
5431
- // already been consumed. To remedy this, whenever `parse_generic_args` is invoked, we
5432
- // make a snapshot of the current parser state and invoke it on that and inspect
5433
- // the result:
5434
- //
5435
- // - If success (ie. when it found a matching `>` character) then the snapshot state
5436
- // is kept (this is required to propagate the count upwards).
5437
- //
5438
- // - If error and in was in a recursive call, then the snapshot state is kept (this is
5439
- // required to propagate the count upwards).
5440
- //
5441
- // - If error and this was the first invocation (before any recursion had taken place)
5442
- // then we choose not to keep the snapshot state - that way we haven't actually
5443
- // consumed any of the `<` characters, but can still inspect the count from the
5444
- // snapshot to know how many `<` characters to remove. Using this information, we can
5445
- // emit an error and consume the extra `<` characters before attempting to parse
5446
- // the generic arguments again (this time hopefullt successfully as the unmatched `<`
5447
- // characters are gone).
5431
+ // already been consumed. To remedy this, we keep a snapshot of the parser state
5432
+ // before we do the above. We can then inspect whether we ended up with a parsing error
5433
+ // and unmatched left angle brackets and if so, restore the parser state before we
5434
+ // consumed any `<` characters to emit an error and consume the erroneous tokens to
5435
+ // recover by attempting to parse again.
5448
5436
//
5449
5437
// In practice, the recursion of this function is indirect and there will be other
5450
5438
// locations that consume some `<` characters - as long as we update the count when
5451
5439
// this happens, it isn't an issue.
5452
- let mut snapshot = self . clone ( ) ;
5440
+
5441
+ let is_first_invocation = style == PathStyle :: Expr ;
5442
+ // Take a snapshot before attempting to parse - we can restore this later.
5443
+ let snapshot = if is_first_invocation {
5444
+ Some ( self . clone ( ) )
5445
+ } else {
5446
+ None
5447
+ } ;
5448
+
5453
5449
debug ! ( "parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)" ) ;
5454
- match snapshot. parse_generic_args ( ) {
5455
- Ok ( value) => {
5456
- debug ! (
5457
- "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot success) \
5458
- snapshot.count={:?}",
5459
- snapshot. unmatched_angle_bracket_count,
5460
- ) ;
5461
- mem:: replace ( self , snapshot) ;
5462
- Ok ( value)
5463
- } ,
5464
- Err ( mut e) => {
5450
+ match self . parse_generic_args ( ) {
5451
+ Ok ( value) => Ok ( value) ,
5452
+ Err ( ref mut e) if is_first_invocation && self . unmatched_angle_bracket_count > 0 => {
5453
+ // Cancel error from being unable to find `>`. We know the error
5454
+ // must have been this due to a non-zero unmatched angle bracket
5455
+ // count.
5456
+ e. cancel ( ) ;
5457
+
5458
+ // Swap `self` with our backup of the parser state before attempting to parse
5459
+ // generic arguments.
5460
+ let snapshot = mem:: replace ( self , snapshot. unwrap ( ) ) ;
5461
+
5465
5462
debug ! (
5466
5463
"parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \
5467
5464
snapshot.count={:?}",
5468
5465
snapshot. unmatched_angle_bracket_count,
5469
5466
) ;
5470
- if style == PathStyle :: Expr && snapshot. unmatched_angle_bracket_count > 0 {
5471
- // Cancel error from being unable to find `>`. We know the error
5472
- // must have been this due to a non-zero unmatched angle bracket
5473
- // count.
5474
- e. cancel ( ) ;
5475
-
5476
- // Eat the unmatched angle brackets.
5477
- for _ in 0 ..snapshot. unmatched_angle_bracket_count {
5478
- self . eat_lt ( ) ;
5479
- }
5480
5467
5481
- // Make a span over ${unmatched angle bracket count} characters.
5482
- let span = lo. with_hi (
5483
- lo. lo ( ) + BytePos ( snapshot. unmatched_angle_bracket_count )
5484
- ) ;
5485
- let plural = snapshot. unmatched_angle_bracket_count > 1 ;
5486
- self . diagnostic ( )
5487
- . struct_span_err (
5488
- span,
5489
- & format ! (
5490
- "unmatched angle bracket{}" ,
5491
- if plural { "s" } else { "" }
5492
- ) ,
5493
- )
5494
- . span_suggestion_with_applicability (
5495
- span,
5496
- & format ! (
5497
- "remove extra angle bracket{}" ,
5498
- if plural { "s" } else { "" }
5499
- ) ,
5500
- String :: new ( ) ,
5501
- Applicability :: MachineApplicable ,
5502
- )
5503
- . emit ( ) ;
5504
-
5505
- // Try again without unmatched angle bracket characters.
5506
- self . parse_generic_args ( )
5507
- } else {
5508
- mem:: replace ( self , snapshot) ;
5509
- Err ( e)
5468
+ // Eat the unmatched angle brackets.
5469
+ for _ in 0 ..snapshot. unmatched_angle_bracket_count {
5470
+ self . eat_lt ( ) ;
5510
5471
}
5472
+
5473
+ // Make a span over ${unmatched angle bracket count} characters.
5474
+ let span = lo. with_hi (
5475
+ lo. lo ( ) + BytePos ( snapshot. unmatched_angle_bracket_count )
5476
+ ) ;
5477
+ let plural = snapshot. unmatched_angle_bracket_count > 1 ;
5478
+ self . diagnostic ( )
5479
+ . struct_span_err (
5480
+ span,
5481
+ & format ! (
5482
+ "unmatched angle bracket{}" ,
5483
+ if plural { "s" } else { "" }
5484
+ ) ,
5485
+ )
5486
+ . span_suggestion_with_applicability (
5487
+ span,
5488
+ & format ! (
5489
+ "remove extra angle bracket{}" ,
5490
+ if plural { "s" } else { "" }
5491
+ ) ,
5492
+ String :: new ( ) ,
5493
+ Applicability :: MachineApplicable ,
5494
+ )
5495
+ . emit ( ) ;
5496
+
5497
+ // Try again without unmatched angle bracket characters.
5498
+ self . parse_generic_args ( )
5511
5499
} ,
5500
+ Err ( e) => Err ( e) ,
5512
5501
}
5513
5502
}
5514
5503
0 commit comments