@@ -17,7 +17,6 @@ use rustc_span::symbol::kw;
1717use rustc_span:: { MultiSpan , Span , SpanSnippetError , DUMMY_SP } ;
1818
1919use log:: { debug, trace} ;
20- use std:: mem;
2120
2221const TURBOFISH : & str = "use `::<...>` instead of `<...>` to specify type arguments" ;
2322
@@ -459,7 +458,7 @@ impl<'a> Parser<'a> {
459458 err : & mut DiagnosticBuilder < ' _ > ,
460459 inner_op : & Expr ,
461460 outer_op : & Spanned < AssocOp > ,
462- ) -> bool /* recover */ {
461+ ) -> bool /* advanced the cursor */ {
463462 if let ExprKind :: Binary ( op, ref l1, ref r1) = inner_op. kind {
464463 if let ExprKind :: Field ( _, ident) = l1. kind {
465464 if ident. as_str ( ) . parse :: < i32 > ( ) . is_err ( ) && !matches ! ( r1. kind, ExprKind :: Lit ( _) ) {
@@ -468,6 +467,16 @@ impl<'a> Parser<'a> {
468467 return false ;
469468 }
470469 }
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+ } ;
471480 return match ( op. node , & outer_op. node ) {
472481 // `x == y == z`
473482 ( BinOpKind :: Eq , AssocOp :: Equal ) |
@@ -492,23 +501,18 @@ impl<'a> Parser<'a> {
492501 // `x == y < z`
493502 ( BinOpKind :: Eq , AssocOp :: Less ) | ( BinOpKind :: Eq , AssocOp :: LessEqual ) |
494503 ( BinOpKind :: Eq , AssocOp :: Greater ) | ( BinOpKind :: Eq , AssocOp :: GreaterEqual ) => {
495- // Consume `/` z`/outer-op-rhs.
504+ // Consume `z`/outer-op-rhs.
496505 let snapshot = self . clone ( ) ;
497506 match self . parse_expr ( ) {
498507 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 ) ;
507511 true
508512 }
509513 Err ( mut expr_err) => {
510514 expr_err. cancel ( ) ;
511- mem :: replace ( self , snapshot) ;
515+ * self = snapshot;
512516 false
513517 }
514518 }
@@ -517,21 +521,16 @@ impl<'a> Parser<'a> {
517521 ( BinOpKind :: Lt , AssocOp :: Equal ) | ( BinOpKind :: Le , AssocOp :: Equal ) |
518522 ( BinOpKind :: Gt , AssocOp :: Equal ) | ( BinOpKind :: Ge , AssocOp :: Equal ) => {
519523 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.
528526 match self . parse_expr ( ) {
529527 Ok ( _) => {
528+ enclose ( l1. span , r1. span ) ;
530529 true
531530 }
532531 Err ( mut expr_err) => {
533532 expr_err. cancel ( ) ;
534- mem :: replace ( self , snapshot) ;
533+ * self = snapshot;
535534 false
536535 }
537536 }
@@ -588,11 +587,11 @@ impl<'a> Parser<'a> {
588587 ) ;
589588 } ;
590589
590+ // Include `<` to provide this recommendation even in a case like
591+ // `Foo<Bar<Baz<Qux, ()>>>`
591592 if op. node == BinOpKind :: Lt && outer_op. node == AssocOp :: Less
592593 || outer_op. node == AssocOp :: Greater
593594 {
594- // Include `<` to provide this recommendation
595- // even in a case like `Foo<Bar<Baz<Qux, ()>>>`
596595 if outer_op. node == AssocOp :: Less {
597596 let snapshot = self . clone ( ) ;
598597 self . bump ( ) ;
@@ -606,7 +605,7 @@ impl<'a> Parser<'a> {
606605 {
607606 // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
608607 // parser and bail out.
609- mem :: replace ( self , snapshot. clone ( ) ) ;
608+ * self = snapshot. clone ( ) ;
610609 }
611610 }
612611 return if token:: ModSep == self . token . kind {
@@ -631,7 +630,7 @@ impl<'a> Parser<'a> {
631630 expr_err. cancel ( ) ;
632631 // Not entirely sure now, but we bubble the error up with the
633632 // suggestion.
634- mem :: replace ( self , snapshot) ;
633+ * self = snapshot;
635634 Err ( err)
636635 }
637636 }
@@ -695,7 +694,7 @@ impl<'a> Parser<'a> {
695694
696695 if self . token . kind == token:: Eof {
697696 // Not entirely sure that what we consumed were fn arguments, rollback.
698- mem :: replace ( self , snapshot) ;
697+ * self = snapshot;
699698 Err ( ( ) )
700699 } else {
701700 // 99% certain that the suggestion is correct, continue parsing.
0 commit comments