@@ -510,7 +510,22 @@ impl Printer<'_> {
510510 }
511511
512512 fn print_expr ( & mut self , expr : ExprId ) {
513+ self . print_expr_in ( None , expr) ;
514+ }
515+
516+ fn print_expr_in ( & mut self , prec : Option < ast:: prec:: ExprPrecedence > , expr : ExprId ) {
513517 let expr = & self . store [ expr] ;
518+ let needs_parens = match ( prec, expr. precedence ( ) ) {
519+ ( Some ( ast:: prec:: ExprPrecedence :: LOr ) , ast:: prec:: ExprPrecedence :: LOr ) => false ,
520+ ( Some ( ast:: prec:: ExprPrecedence :: LAnd ) , ast:: prec:: ExprPrecedence :: LAnd ) => false ,
521+ ( Some ( parent) , prec) => prec. needs_parentheses_in ( parent) ,
522+ ( None , _) => false ,
523+ } ;
524+ let prec = Some ( expr. precedence ( ) ) ;
525+
526+ if needs_parens {
527+ w ! ( self , "(" ) ;
528+ }
514529
515530 match expr {
516531 Expr :: Missing => w ! ( self , "�" ) ,
@@ -544,7 +559,7 @@ impl Printer<'_> {
544559 w ! ( self , "let " ) ;
545560 self . print_pat ( * pat) ;
546561 w ! ( self , " = " ) ;
547- self . print_expr ( * expr) ;
562+ self . print_expr_in ( prec , * expr) ;
548563 }
549564 Expr :: Loop { body, label } => {
550565 if let Some ( lbl) = label {
@@ -554,7 +569,7 @@ impl Printer<'_> {
554569 self . print_expr ( * body) ;
555570 }
556571 Expr :: Call { callee, args } => {
557- self . print_expr ( * callee) ;
572+ self . print_expr_in ( prec , * callee) ;
558573 w ! ( self , "(" ) ;
559574 if !args. is_empty ( ) {
560575 self . indented ( |p| {
@@ -567,7 +582,7 @@ impl Printer<'_> {
567582 w ! ( self , ")" ) ;
568583 }
569584 Expr :: MethodCall { receiver, method_name, args, generic_args } => {
570- self . print_expr ( * receiver) ;
585+ self . print_expr_in ( prec , * receiver) ;
571586 w ! ( self , ".{}" , method_name. display( self . db, self . edition) ) ;
572587 if let Some ( args) = generic_args {
573588 w ! ( self , "::<" ) ;
@@ -616,26 +631,26 @@ impl Printer<'_> {
616631 }
617632 if let Some ( expr) = expr {
618633 self . whitespace ( ) ;
619- self . print_expr ( * expr) ;
634+ self . print_expr_in ( prec , * expr) ;
620635 }
621636 }
622637 Expr :: Return { expr } => {
623638 w ! ( self , "return" ) ;
624639 if let Some ( expr) = expr {
625640 self . whitespace ( ) ;
626- self . print_expr ( * expr) ;
641+ self . print_expr_in ( prec , * expr) ;
627642 }
628643 }
629644 Expr :: Become { expr } => {
630645 w ! ( self , "become" ) ;
631646 self . whitespace ( ) ;
632- self . print_expr ( * expr) ;
647+ self . print_expr_in ( prec , * expr) ;
633648 }
634649 Expr :: Yield { expr } => {
635650 w ! ( self , "yield" ) ;
636651 if let Some ( expr) = expr {
637652 self . whitespace ( ) ;
638- self . print_expr ( * expr) ;
653+ self . print_expr_in ( prec , * expr) ;
639654 }
640655 }
641656 Expr :: Yeet { expr } => {
@@ -644,7 +659,7 @@ impl Printer<'_> {
644659 w ! ( self , "yeet" ) ;
645660 if let Some ( expr) = expr {
646661 self . whitespace ( ) ;
647- self . print_expr ( * expr) ;
662+ self . print_expr_in ( prec , * expr) ;
648663 }
649664 }
650665 Expr :: RecordLit { path, fields, spread } => {
@@ -670,15 +685,15 @@ impl Printer<'_> {
670685 w ! ( self , "}}" ) ;
671686 }
672687 Expr :: Field { expr, name } => {
673- self . print_expr ( * expr) ;
688+ self . print_expr_in ( prec , * expr) ;
674689 w ! ( self , ".{}" , name. display( self . db, self . edition) ) ;
675690 }
676691 Expr :: Await { expr } => {
677- self . print_expr ( * expr) ;
692+ self . print_expr_in ( prec , * expr) ;
678693 w ! ( self , ".await" ) ;
679694 }
680695 Expr :: Cast { expr, type_ref } => {
681- self . print_expr ( * expr) ;
696+ self . print_expr_in ( prec , * expr) ;
682697 w ! ( self , " as " ) ;
683698 self . print_type_ref ( * type_ref) ;
684699 }
@@ -690,11 +705,11 @@ impl Printer<'_> {
690705 if mutability. is_mut ( ) {
691706 w ! ( self , "mut " ) ;
692707 }
693- self . print_expr ( * expr) ;
708+ self . print_expr_in ( prec , * expr) ;
694709 }
695710 Expr :: Box { expr } => {
696711 w ! ( self , "box " ) ;
697- self . print_expr ( * expr) ;
712+ self . print_expr_in ( prec , * expr) ;
698713 }
699714 Expr :: UnaryOp { expr, op } => {
700715 let op = match op {
@@ -703,43 +718,32 @@ impl Printer<'_> {
703718 ast:: UnaryOp :: Neg => "-" ,
704719 } ;
705720 w ! ( self , "{}" , op) ;
706- self . print_expr ( * expr) ;
721+ self . print_expr_in ( prec , * expr) ;
707722 }
708723 Expr :: BinaryOp { lhs, rhs, op } => {
709- let ( bra, ket) = match op {
710- None | Some ( ast:: BinaryOp :: Assignment { .. } ) => ( "" , "" ) ,
711- _ => ( "(" , ")" ) ,
712- } ;
713- w ! ( self , "{}" , bra) ;
714- self . print_expr ( * lhs) ;
715- w ! ( self , "{} " , ket) ;
724+ self . print_expr_in ( prec, * lhs) ;
725+ self . whitespace ( ) ;
716726 match op {
717727 Some ( op) => w ! ( self , "{}" , op) ,
718728 None => w ! ( self , "�" ) , // :)
719729 }
720- w ! ( self , " {}" , bra) ;
721- self . print_expr ( * rhs) ;
722- w ! ( self , "{}" , ket) ;
730+ self . whitespace ( ) ;
731+ self . print_expr_in ( prec, * rhs) ;
723732 }
724733 Expr :: Range { lhs, rhs, range_type } => {
725734 if let Some ( lhs) = lhs {
726- w ! ( self , "(" ) ;
727- self . print_expr ( * lhs) ;
728- w ! ( self , ") " ) ;
735+ self . print_expr_in ( prec, * lhs) ;
729736 }
730- let range = match range_type {
731- ast:: RangeOp :: Exclusive => ".." ,
732- ast:: RangeOp :: Inclusive => "..=" ,
737+ match range_type {
738+ ast:: RangeOp :: Exclusive => w ! ( self , ".." ) ,
739+ ast:: RangeOp :: Inclusive => w ! ( self , "..=" ) ,
733740 } ;
734- w ! ( self , "{}" , range) ;
735741 if let Some ( rhs) = rhs {
736- w ! ( self , "(" ) ;
737- self . print_expr ( * rhs) ;
738- w ! ( self , ") " ) ;
742+ self . print_expr_in ( prec, * rhs) ;
739743 }
740744 }
741745 Expr :: Index { base, index } => {
742- self . print_expr ( * base) ;
746+ self . print_expr_in ( prec , * base) ;
743747 w ! ( self , "[" ) ;
744748 self . print_expr ( * index) ;
745749 w ! ( self , "]" ) ;
@@ -826,9 +830,13 @@ impl Printer<'_> {
826830 & Expr :: Assignment { target, value } => {
827831 self . print_pat ( target) ;
828832 w ! ( self , " = " ) ;
829- self . print_expr ( value) ;
833+ self . print_expr_in ( prec , value) ;
830834 }
831835 }
836+
837+ if needs_parens {
838+ w ! ( self , ")" ) ;
839+ }
832840 }
833841
834842 fn print_block (
@@ -857,6 +865,7 @@ impl Printer<'_> {
857865 }
858866
859867 fn print_pat ( & mut self , pat : PatId ) {
868+ let prec = Some ( ast:: prec:: ExprPrecedence :: Shift ) ;
860869 let pat = & self . store [ pat] ;
861870
862871 match pat {
@@ -930,11 +939,11 @@ impl Printer<'_> {
930939 }
931940 Pat :: Range { start, end } => {
932941 if let Some ( start) = start {
933- self . print_expr ( * start) ;
942+ self . print_expr_in ( prec , * start) ;
934943 }
935944 w ! ( self , "..=" ) ;
936945 if let Some ( end) = end {
937- self . print_expr ( * end) ;
946+ self . print_expr_in ( prec , * end) ;
938947 }
939948 }
940949 Pat :: Slice { prefix, slice, suffix } => {
@@ -954,7 +963,7 @@ impl Printer<'_> {
954963 w ! ( self , "]" ) ;
955964 }
956965 Pat :: Path ( path) => self . print_path ( path) ,
957- Pat :: Lit ( expr) => self . print_expr ( * expr) ,
966+ Pat :: Lit ( expr) => self . print_expr_in ( prec , * expr) ,
958967 Pat :: Bind { id, subpat } => {
959968 self . print_binding ( * id) ;
960969 if let Some ( pat) = subpat {
@@ -996,7 +1005,7 @@ impl Printer<'_> {
9961005 self . print_expr ( * c) ;
9971006 }
9981007 Pat :: Expr ( expr) => {
999- self . print_expr ( * expr) ;
1008+ self . print_expr_in ( prec , * expr) ;
10001009 }
10011010 }
10021011 }
@@ -1181,7 +1190,9 @@ impl Printer<'_> {
11811190 pub ( crate ) fn print_generic_arg ( & mut self , arg : & GenericArg ) {
11821191 match arg {
11831192 GenericArg :: Type ( ty) => self . print_type_ref ( * ty) ,
1184- GenericArg :: Const ( ConstRef { expr } ) => self . print_expr ( * expr) ,
1193+ GenericArg :: Const ( ConstRef { expr } ) => {
1194+ self . print_expr_in ( Some ( ast:: prec:: ExprPrecedence :: Unambiguous ) , * expr)
1195+ }
11851196 GenericArg :: Lifetime ( lt) => self . print_lifetime_ref ( * lt) ,
11861197 }
11871198 }
0 commit comments