@@ -5428,87 +5428,76 @@ impl<'a> Parser<'a> {
54285428 //
54295429 // In doing this, we have managed to work out how many unmatched leading left angle
54305430 // 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.
54485436 //
54495437 // In practice, the recursion of this function is indirect and there will be other
54505438 // locations that consume some `<` characters - as long as we update the count when
54515439 // 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+
54535449 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+
54655462 debug ! (
54665463 "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \
54675464 snapshot.count={:?}",
54685465 snapshot. unmatched_angle_bracket_count,
54695466 ) ;
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- }
54805467
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 ( ) ;
55105471 }
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 ( )
55115499 } ,
5500+ Err ( e) => Err ( e) ,
55125501 }
55135502 }
55145503
0 commit comments