@@ -352,49 +352,59 @@ impl<'a> Parser<'a> {
352
352
debug ! ( "parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)" ) ;
353
353
match self . parse_angle_args ( ) {
354
354
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 => {
361
356
// Swap `self` with our backup of the parser state before attempting to parse
362
357
// generic arguments.
363
358
let snapshot = mem:: replace ( self , snapshot. unwrap ( ) ) ;
364
359
365
- debug ! (
366
- "parse_generic_args_with_leading_angle_bracket_recovery: (snapshot failure) \
367
- snapshot.count={:?}",
368
- snapshot. unmatched_angle_bracket_count,
369
- ) ;
370
-
371
360
// 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 ( ) ;
395
404
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
+ }
398
408
}
399
409
Err ( e) => Err ( e) ,
400
410
}
0 commit comments