@@ -285,7 +285,7 @@ impl FixupContext {
285285 fn leftmost_subexpression_precedence ( self , expr : & Expr ) -> Precedence {
286286 #[ cfg( feature = "full" ) ]
287287 if !self . next_operator_can_begin_expr || self . next_operator == Precedence :: Range {
288- if let Scan :: Bailout = scan_right ( expr, self , false , 0 , 0 ) {
288+ if let Scan :: Bailout = scan_right ( expr, self , Precedence :: MIN , 0 , 0 ) {
289289 if scan_left ( expr, self ) {
290290 return Precedence :: Unambiguous ;
291291 }
@@ -354,13 +354,8 @@ impl FixupContext {
354354 if default_prec < Precedence :: Prefix
355355 && ( !self . next_operator_can_begin_expr || self . next_operator == Precedence :: Range )
356356 {
357- if let Scan :: Bailout | Scan :: Fail = scan_right (
358- expr,
359- self ,
360- self . previous_operator == Precedence :: Range ,
361- 1 ,
362- 0 ,
363- ) {
357+ if let Scan :: Bailout | Scan :: Fail = scan_right ( expr, self , self . previous_operator , 1 , 0 )
358+ {
364359 if scan_left ( expr, self ) {
365360 return Precedence :: Prefix ;
366361 }
@@ -467,6 +462,13 @@ impl Clone for Scan {
467462 }
468463}
469464
465+ #[ cfg( feature = "full" ) ]
466+ impl PartialEq for Scan {
467+ fn eq ( & self , other : & Self ) -> bool {
468+ * self as u8 == * other as u8
469+ }
470+ }
471+
470472#[ cfg( feature = "full" ) ]
471473fn scan_left ( expr : & Expr , fixup : FixupContext ) -> bool {
472474 match expr {
@@ -485,12 +487,21 @@ fn scan_left(expr: &Expr, fixup: FixupContext) -> bool {
485487fn scan_right (
486488 expr : & Expr ,
487489 fixup : FixupContext ,
488- range : bool ,
490+ precedence : Precedence ,
489491 fail_offset : u8 ,
490492 bailout_offset : u8 ,
491493) -> Scan {
494+ let consume_by_precedence = if match precedence {
495+ Precedence :: Assign | Precedence :: Compare => precedence <= fixup. next_operator ,
496+ _ => precedence < fixup. next_operator ,
497+ } || fixup. next_operator == Precedence :: MIN
498+ {
499+ Scan :: Consume
500+ } else {
501+ Scan :: Bailout
502+ } ;
492503 if fixup. parenthesize ( expr) {
493- return Scan :: Consume ;
504+ return consume_by_precedence ;
494505 }
495506 match expr {
496507 Expr :: Assign ( e) => {
@@ -504,7 +515,7 @@ fn scan_right(
504515 let scan = scan_right (
505516 & e. right ,
506517 right_fixup,
507- false ,
518+ Precedence :: Assign ,
508519 match fixup. next_operator {
509520 Precedence :: Unambiguous => fail_offset,
510521 _ => 1 ,
@@ -521,7 +532,10 @@ fn scan_right(
521532 }
522533 Expr :: Binary ( e) => {
523534 if match fixup. next_operator {
524- Precedence :: Unambiguous => fail_offset >= 2 ,
535+ Precedence :: Unambiguous => {
536+ fail_offset >= 2
537+ && ( consume_by_precedence == Scan :: Consume || bailout_offset >= 1 )
538+ }
525539 _ => bailout_offset >= 1 ,
526540 } {
527541 return Scan :: Consume ;
@@ -531,29 +545,22 @@ fn scan_right(
531545 let scan = scan_right (
532546 & e. right ,
533547 right_fixup,
534- range && binop_prec != Precedence :: Assign ,
548+ binop_prec,
535549 match fixup. next_operator {
536550 Precedence :: Unambiguous => fail_offset,
537551 _ => 1 ,
538552 } ,
539- match ( binop_prec, fixup. next_operator ) {
540- ( Precedence :: Assign , _) => 1 ,
541- ( _, Precedence :: Assign | Precedence :: Range ) if range => 0 ,
542- _ => 1 ,
543- } ,
553+ consume_by_precedence as u8 - Scan :: Bailout as u8 ,
544554 ) ;
545- if match ( scan, fixup. next_operator ) {
546- ( Scan :: Fail , _) => false ,
547- ( Scan :: Bailout , _) if binop_prec == Precedence :: Assign => true ,
548- ( Scan :: Bailout , Precedence :: Assign | Precedence :: Range ) => !range,
549- ( Scan :: Bailout | Scan :: Consume , _) => true ,
550- } {
551- return Scan :: Consume ;
555+ match scan {
556+ Scan :: Fail => { }
557+ Scan :: Bailout => return consume_by_precedence,
558+ Scan :: Consume => return Scan :: Consume ,
552559 }
553560 let right_needs_group = binop_prec != Precedence :: Assign
554561 && right_fixup. rightmost_subexpression_precedence ( & e. right ) <= binop_prec;
555562 if right_needs_group {
556- Scan :: Consume
563+ consume_by_precedence
557564 } else if let ( Scan :: Fail , Precedence :: Unambiguous ) = ( scan, fixup. next_operator ) {
558565 Scan :: Fail
559566 } else {
@@ -564,7 +571,10 @@ fn scan_right(
564571 | Expr :: Reference ( ExprReference { expr, .. } )
565572 | Expr :: Unary ( ExprUnary { expr, .. } ) => {
566573 if match fixup. next_operator {
567- Precedence :: Unambiguous => fail_offset >= 2 ,
574+ Precedence :: Unambiguous => {
575+ fail_offset >= 2
576+ && ( consume_by_precedence == Scan :: Consume || bailout_offset >= 1 )
577+ }
568578 _ => bailout_offset >= 1 ,
569579 } {
570580 return Scan :: Consume ;
@@ -573,25 +583,20 @@ fn scan_right(
573583 let scan = scan_right (
574584 expr,
575585 right_fixup,
576- range ,
586+ precedence ,
577587 match fixup. next_operator {
578588 Precedence :: Unambiguous => fail_offset,
579589 _ => 1 ,
580590 } ,
581- match fixup. next_operator {
582- Precedence :: Assign | Precedence :: Range if range => 0 ,
583- _ => 1 ,
584- } ,
591+ consume_by_precedence as u8 - Scan :: Bailout as u8 ,
585592 ) ;
586- if match ( scan, fixup. next_operator ) {
587- ( Scan :: Fail , _) => false ,
588- ( Scan :: Bailout , Precedence :: Assign | Precedence :: Range ) => !range,
589- ( Scan :: Bailout | Scan :: Consume , _) => true ,
590- } {
591- return Scan :: Consume ;
593+ match scan {
594+ Scan :: Fail => { }
595+ Scan :: Bailout => return consume_by_precedence,
596+ Scan :: Consume => return Scan :: Consume ,
592597 }
593598 if right_fixup. rightmost_subexpression_precedence ( expr) < Precedence :: Prefix {
594- Scan :: Consume
599+ consume_by_precedence
595600 } else if let ( Scan :: Fail , Precedence :: Unambiguous ) = ( scan, fixup. next_operator ) {
596601 Scan :: Fail
597602 } else {
@@ -608,7 +613,7 @@ fn scan_right(
608613 let scan = scan_right (
609614 end,
610615 right_fixup,
611- true ,
616+ Precedence :: Range ,
612617 fail_offset,
613618 match fixup. next_operator {
614619 Precedence :: Assign | Precedence :: Range => 0 ,
@@ -639,13 +644,13 @@ fn scan_right(
639644 return Scan :: Consume ;
640645 }
641646 let right_fixup = fixup. rightmost_subexpression_fixup ( true , true , Precedence :: Jump ) ;
642- match scan_right ( value, right_fixup, false , 1 , 1 ) {
647+ match scan_right ( value, right_fixup, Precedence :: Jump , 1 , 1 ) {
643648 Scan :: Fail => Scan :: Bailout ,
644649 Scan :: Bailout | Scan :: Consume => Scan :: Consume ,
645650 }
646651 }
647652 None => match fixup. next_operator {
648- Precedence :: Assign if range => Scan :: Fail ,
653+ Precedence :: Assign if precedence > Precedence :: Assign => Scan :: Fail ,
649654 _ => Scan :: Consume ,
650655 } ,
651656 } ,
@@ -656,13 +661,13 @@ fn scan_right(
656661 }
657662 let right_fixup =
658663 fixup. rightmost_subexpression_fixup ( true , false , Precedence :: Jump ) ;
659- match scan_right ( e, right_fixup, false , 1 , 1 ) {
664+ match scan_right ( e, right_fixup, Precedence :: Jump , 1 , 1 ) {
660665 Scan :: Fail => Scan :: Bailout ,
661666 Scan :: Bailout | Scan :: Consume => Scan :: Consume ,
662667 }
663668 }
664669 None => match fixup. next_operator {
665- Precedence :: Assign if range => Scan :: Fail ,
670+ Precedence :: Assign if precedence > Precedence :: Assign => Scan :: Fail ,
666671 _ => Scan :: Consume ,
667672 } ,
668673 } ,
@@ -675,7 +680,7 @@ fn scan_right(
675680 }
676681 let right_fixup =
677682 fixup. rightmost_subexpression_fixup ( false , false , Precedence :: Jump ) ;
678- match scan_right ( & e. body , right_fixup, false , 1 , 1 ) {
683+ match scan_right ( & e. body , right_fixup, Precedence :: Jump , 1 , 1 ) {
679684 Scan :: Fail => Scan :: Bailout ,
680685 Scan :: Bailout | Scan :: Consume => Scan :: Consume ,
681686 }
@@ -713,8 +718,8 @@ fn scan_right(
713718 | Expr :: Unsafe ( _)
714719 | Expr :: Verbatim ( _)
715720 | Expr :: While ( _) => match fixup. next_operator {
716- Precedence :: Assign | Precedence :: Range if range => Scan :: Fail ,
717- _ => Scan :: Consume ,
721+ Precedence :: Assign | Precedence :: Range if precedence == Precedence :: Range => Scan :: Fail ,
722+ _ => consume_by_precedence ,
718723 } ,
719724 }
720725}
0 commit comments