@@ -17,7 +17,6 @@ use rustc_span::symbol::kw;
17
17
use rustc_span:: { MultiSpan , Span , SpanSnippetError , DUMMY_SP } ;
18
18
19
19
use log:: { debug, trace} ;
20
- use std:: mem;
21
20
22
21
const TURBOFISH : & str = "use `::<...>` instead of `<...>` to specify type arguments" ;
23
22
@@ -459,7 +458,7 @@ impl<'a> Parser<'a> {
459
458
err : & mut DiagnosticBuilder < ' _ > ,
460
459
inner_op : & Expr ,
461
460
outer_op : & Spanned < AssocOp > ,
462
- ) -> bool /* recover */ {
461
+ ) -> bool /* advanced the cursor */ {
463
462
if let ExprKind :: Binary ( op, ref l1, ref r1) = inner_op. kind {
464
463
if let ExprKind :: Field ( _, ident) = l1. kind {
465
464
if ident. as_str ( ) . parse :: < i32 > ( ) . is_err ( ) && !matches ! ( r1. kind, ExprKind :: Lit ( _) ) {
@@ -468,6 +467,16 @@ impl<'a> Parser<'a> {
468
467
return false ;
469
468
}
470
469
}
470
+ let mut enclose = |left : Span , right : Span | {
471
+ err. multipart_suggestion (
472
+ "parenthesize the comparison" ,
473
+ vec ! [
474
+ ( left. shrink_to_lo( ) , "(" . to_string( ) ) ,
475
+ ( right. shrink_to_hi( ) , ")" . to_string( ) ) ,
476
+ ] ,
477
+ Applicability :: MaybeIncorrect ,
478
+ ) ;
479
+ } ;
471
480
return match ( op. node , & outer_op. node ) {
472
481
// `x == y == z`
473
482
( BinOpKind :: Eq , AssocOp :: Equal ) |
@@ -492,23 +501,18 @@ impl<'a> Parser<'a> {
492
501
// `x == y < z`
493
502
( BinOpKind :: Eq , AssocOp :: Less ) | ( BinOpKind :: Eq , AssocOp :: LessEqual ) |
494
503
( BinOpKind :: Eq , AssocOp :: Greater ) | ( BinOpKind :: Eq , AssocOp :: GreaterEqual ) => {
495
- // Consume `/` z`/outer-op-rhs.
504
+ // Consume `z`/outer-op-rhs.
496
505
let snapshot = self . clone ( ) ;
497
506
match self . parse_expr ( ) {
498
507
Ok ( r2) => {
499
- err. multipart_suggestion (
500
- "parenthesize the comparison" ,
501
- vec ! [
502
- ( r1. span. shrink_to_lo( ) , "(" . to_string( ) ) ,
503
- ( r2. span. shrink_to_hi( ) , ")" . to_string( ) ) ,
504
- ] ,
505
- Applicability :: MaybeIncorrect ,
506
- ) ;
508
+ // We are sure that outer-op-rhs could be consumed, the suggestion is
509
+ // likely correct.
510
+ enclose ( r1. span , r2. span ) ;
507
511
true
508
512
}
509
513
Err ( mut expr_err) => {
510
514
expr_err. cancel ( ) ;
511
- mem :: replace ( self , snapshot) ;
515
+ * self = snapshot;
512
516
false
513
517
}
514
518
}
@@ -517,21 +521,16 @@ impl<'a> Parser<'a> {
517
521
( BinOpKind :: Lt , AssocOp :: Equal ) | ( BinOpKind :: Le , AssocOp :: Equal ) |
518
522
( BinOpKind :: Gt , AssocOp :: Equal ) | ( BinOpKind :: Ge , AssocOp :: Equal ) => {
519
523
let snapshot = self . clone ( ) ;
520
- err. multipart_suggestion (
521
- "parenthesize the comparison" ,
522
- vec ! [
523
- ( l1. span. shrink_to_lo( ) , "(" . to_string( ) ) ,
524
- ( r1. span. shrink_to_hi( ) , ")" . to_string( ) ) ,
525
- ] ,
526
- Applicability :: MaybeIncorrect ,
527
- ) ;
524
+ // At this point it is always valid to enclose the lhs in parentheses, no
525
+ // further checks are necessary.
528
526
match self . parse_expr ( ) {
529
527
Ok ( _) => {
528
+ enclose ( l1. span , r1. span ) ;
530
529
true
531
530
}
532
531
Err ( mut expr_err) => {
533
532
expr_err. cancel ( ) ;
534
- mem :: replace ( self , snapshot) ;
533
+ * self = snapshot;
535
534
false
536
535
}
537
536
}
@@ -588,11 +587,11 @@ impl<'a> Parser<'a> {
588
587
) ;
589
588
} ;
590
589
590
+ // Include `<` to provide this recommendation even in a case like
591
+ // `Foo<Bar<Baz<Qux, ()>>>`
591
592
if op. node == BinOpKind :: Lt && outer_op. node == AssocOp :: Less
592
593
|| outer_op. node == AssocOp :: Greater
593
594
{
594
- // Include `<` to provide this recommendation
595
- // even in a case like `Foo<Bar<Baz<Qux, ()>>>`
596
595
if outer_op. node == AssocOp :: Less {
597
596
let snapshot = self . clone ( ) ;
598
597
self . bump ( ) ;
@@ -606,7 +605,7 @@ impl<'a> Parser<'a> {
606
605
{
607
606
// We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
608
607
// parser and bail out.
609
- mem :: replace ( self , snapshot. clone ( ) ) ;
608
+ * self = snapshot. clone ( ) ;
610
609
}
611
610
}
612
611
return if token:: ModSep == self . token . kind {
@@ -631,7 +630,7 @@ impl<'a> Parser<'a> {
631
630
expr_err. cancel ( ) ;
632
631
// Not entirely sure now, but we bubble the error up with the
633
632
// suggestion.
634
- mem :: replace ( self , snapshot) ;
633
+ * self = snapshot;
635
634
Err ( err)
636
635
}
637
636
}
@@ -695,7 +694,7 @@ impl<'a> Parser<'a> {
695
694
696
695
if self . token . kind == token:: Eof {
697
696
// Not entirely sure that what we consumed were fn arguments, rollback.
698
- mem :: replace ( self , snapshot) ;
697
+ * self = snapshot;
699
698
Err ( ( ) )
700
699
} else {
701
700
// 99% certain that the suggestion is correct, continue parsing.
0 commit comments