@@ -352,49 +352,59 @@ impl<'a> Parser<'a> {
352352 debug ! ( "parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)" ) ;
353353 match self . parse_angle_args ( ) {
354354 Ok ( args) => Ok ( args) ,
355- Err ( ref mut e) if is_first_invocation && self . unmatched_angle_bracket_count > 0 => {
356- // Cancel error from being unable to find `>`. We know the error
357- // must have been this due to a non-zero unmatched angle bracket
358- // count.
359- e. cancel ( ) ;
360-
355+ Err ( mut e) if is_first_invocation && self . unmatched_angle_bracket_count > 0 => {
361356 // Swap `self` with our backup of the parser state before attempting to parse
362357 // generic arguments.
363358 let snapshot = mem:: replace ( self , snapshot. unwrap ( ) ) ;
364359
365- debug ! (
366- "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \
367- snapshot.count={:?}",
368- snapshot. unmatched_angle_bracket_count,
369- ) ;
370-
371360 // Eat the unmatched angle brackets.
372- for _ in 0 ..snapshot. unmatched_angle_bracket_count {
373- self . eat_lt ( ) ;
374- }
375-
376- // Make a span over ${unmatched angle bracket count} characters.
377- let span = lo. with_hi ( lo. lo ( ) + BytePos ( snapshot. unmatched_angle_bracket_count ) ) ;
378- self . struct_span_err (
379- span,
380- & format ! (
381- "unmatched angle bracket{}" ,
382- pluralize!( snapshot. unmatched_angle_bracket_count)
383- ) ,
384- )
385- . span_suggestion (
386- span,
387- & format ! (
388- "remove extra angle bracket{}" ,
389- pluralize!( snapshot. unmatched_angle_bracket_count)
390- ) ,
391- String :: new ( ) ,
392- Applicability :: MachineApplicable ,
393- )
394- . emit ( ) ;
361+ let all_angle_brackets = ( 0 ..snapshot. unmatched_angle_bracket_count )
362+ . fold ( true , |a, _| a && self . eat_lt ( ) ) ;
363+
364+ if !all_angle_brackets {
365+ // If there are other tokens in between the extraneous `<`s, we cannot simply
366+ // suggest to remove them. This check also prevents us from accidentally ending
367+ // up in the middle of a multibyte character (issue #84104).
368+ let _ = mem:: replace ( self , snapshot) ;
369+ Err ( e)
370+ } else {
371+ // Cancel error from being unable to find `>`. We know the error
372+ // must have been this due to a non-zero unmatched angle bracket
373+ // count.
374+ e. cancel ( ) ;
375+
376+ debug ! (
377+ "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \
378+ snapshot.count={:?}",
379+ snapshot. unmatched_angle_bracket_count,
380+ ) ;
381+
382+ // Make a span over ${unmatched angle bracket count} characters.
383+ // This is safe because `all_angle_brackets` ensures that there are only `<`s,
384+ // i.e. no multibyte characters, in this range.
385+ let span =
386+ lo. with_hi ( lo. lo ( ) + BytePos ( snapshot. unmatched_angle_bracket_count ) ) ;
387+ self . struct_span_err (
388+ span,
389+ & format ! (
390+ "unmatched angle bracket{}" ,
391+ pluralize!( snapshot. unmatched_angle_bracket_count)
392+ ) ,
393+ )
394+ . span_suggestion (
395+ span,
396+ & format ! (
397+ "remove extra angle bracket{}" ,
398+ pluralize!( snapshot. unmatched_angle_bracket_count)
399+ ) ,
400+ String :: new ( ) ,
401+ Applicability :: MachineApplicable ,
402+ )
403+ . emit ( ) ;
395404
396- // Try again without unmatched angle bracket characters.
397- self . parse_angle_args ( )
405+ // Try again without unmatched angle bracket characters.
406+ self . parse_angle_args ( )
407+ }
398408 }
399409 Err ( e) => Err ( e) ,
400410 }
0 commit comments