@@ -7,6 +7,7 @@ mod item;
77
88use crate :: pp:: Breaks :: { Consistent , Inconsistent } ;
99use crate :: pp:: { self , Breaks } ;
10+ use crate :: pprust:: state:: expr:: FixupContext ;
1011use rustc_ast:: attr:: AttrIdGenerator ;
1112use rustc_ast:: ptr:: P ;
1213use rustc_ast:: token:: { self , BinOpToken , CommentKind , Delimiter , Nonterminal , Token , TokenKind } ;
@@ -811,7 +812,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
811812 }
812813
813814 fn expr_to_string ( & self , e : & ast:: Expr ) -> String {
814- Self :: to_string ( |s| s. print_expr ( e) )
815+ Self :: to_string ( |s| s. print_expr ( e, FixupContext :: default ( ) ) )
815816 }
816817
817818 fn meta_item_lit_to_string ( & self , lit : & ast:: MetaItemLit ) -> String {
@@ -916,7 +917,7 @@ impl<'a> State<'a> {
916917 }
917918
918919 fn commasep_exprs ( & mut self , b : Breaks , exprs : & [ P < ast:: Expr > ] ) {
919- self . commasep_cmnt ( b, exprs, |s, e| s. print_expr ( e) , |e| e. span )
920+ self . commasep_cmnt ( b, exprs, |s, e| s. print_expr ( e, FixupContext :: default ( ) ) , |e| e. span )
920921 }
921922
922923 pub fn print_opt_lifetime ( & mut self , lifetime : & Option < ast:: Lifetime > ) {
@@ -953,7 +954,7 @@ impl<'a> State<'a> {
953954 match generic_arg {
954955 GenericArg :: Lifetime ( lt) => self . print_lifetime ( * lt) ,
955956 GenericArg :: Type ( ty) => self . print_type ( ty) ,
956- GenericArg :: Const ( ct) => self . print_expr ( & ct. value ) ,
957+ GenericArg :: Const ( ct) => self . print_expr ( & ct. value , FixupContext :: default ( ) ) ,
957958 }
958959 }
959960
@@ -1020,12 +1021,12 @@ impl<'a> State<'a> {
10201021 self . word ( "[" ) ;
10211022 self . print_type ( ty) ;
10221023 self . word ( "; " ) ;
1023- self . print_expr ( & length. value ) ;
1024+ self . print_expr ( & length. value , FixupContext :: default ( ) ) ;
10241025 self . word ( "]" ) ;
10251026 }
10261027 ast:: TyKind :: Typeof ( e) => {
10271028 self . word ( "typeof(" ) ;
1028- self . print_expr ( & e. value ) ;
1029+ self . print_expr ( & e. value , FixupContext :: default ( ) ) ;
10291030 self . word ( ")" ) ;
10301031 }
10311032 ast:: TyKind :: Infer => {
@@ -1081,7 +1082,7 @@ impl<'a> State<'a> {
10811082 if let Some ( ( init, els) ) = loc. kind . init_else_opt ( ) {
10821083 self . nbsp ( ) ;
10831084 self . word_space ( "=" ) ;
1084- self . print_expr ( init) ;
1085+ self . print_expr ( init, FixupContext :: default ( ) ) ;
10851086 if let Some ( els) = els {
10861087 self . cbox ( INDENT_UNIT ) ;
10871088 self . ibox ( INDENT_UNIT ) ;
@@ -1095,14 +1096,14 @@ impl<'a> State<'a> {
10951096 ast:: StmtKind :: Item ( item) => self . print_item ( item) ,
10961097 ast:: StmtKind :: Expr ( expr) => {
10971098 self . space_if_not_bol ( ) ;
1098- self . print_expr_outer_attr_style ( expr, false ) ;
1099+ self . print_expr_outer_attr_style ( expr, false , FixupContext :: default ( ) ) ;
10991100 if classify:: expr_requires_semi_to_be_stmt ( expr) {
11001101 self . word ( ";" ) ;
11011102 }
11021103 }
11031104 ast:: StmtKind :: Semi ( expr) => {
11041105 self . space_if_not_bol ( ) ;
1105- self . print_expr_outer_attr_style ( expr, false ) ;
1106+ self . print_expr_outer_attr_style ( expr, false , FixupContext :: default ( ) ) ;
11061107 self . word ( ";" ) ;
11071108 }
11081109 ast:: StmtKind :: Empty => {
@@ -1154,7 +1155,7 @@ impl<'a> State<'a> {
11541155 ast:: StmtKind :: Expr ( expr) if i == blk. stmts . len ( ) - 1 => {
11551156 self . maybe_print_comment ( st. span . lo ( ) ) ;
11561157 self . space_if_not_bol ( ) ;
1157- self . print_expr_outer_attr_style ( expr, false ) ;
1158+ self . print_expr_outer_attr_style ( expr, false , FixupContext :: default ( ) ) ;
11581159 self . maybe_print_trailing_comment ( expr. span , Some ( blk. span . hi ( ) ) ) ;
11591160 }
11601161 _ => self . print_stmt ( st) ,
@@ -1167,13 +1168,41 @@ impl<'a> State<'a> {
11671168 }
11681169
11691170 /// Print a `let pat = expr` expression.
1170- fn print_let ( & mut self , pat : & ast:: Pat , expr : & ast:: Expr ) {
1171+ ///
1172+ /// Parentheses are inserted surrounding `expr` if a round-trip through the
1173+ /// parser would otherwise work out the wrong way in a condition position.
1174+ ///
1175+ /// For example each of the following would mean the wrong thing without
1176+ /// parentheses.
1177+ ///
1178+ /// ```ignore (illustrative)
1179+ /// if let _ = (Struct {}) {}
1180+ ///
1181+ /// if let _ = (true && false) {}
1182+ /// ```
1183+ ///
1184+ /// In a match guard, the second case still requires parens, but the first
1185+ /// case no longer does because anything until `=>` is considered part of
1186+ /// the match guard expression. Parsing of the expression is not terminated
1187+ /// by `{` in that position.
1188+ ///
1189+ /// ```ignore (illustrative)
1190+ /// match () {
1191+ /// () if let _ = Struct {} => {}
1192+ /// () if let _ = (true && false) => {}
1193+ /// }
1194+ /// ```
1195+ fn print_let ( & mut self , pat : & ast:: Pat , expr : & ast:: Expr , fixup : FixupContext ) {
11711196 self . word ( "let " ) ;
11721197 self . print_pat ( pat) ;
11731198 self . space ( ) ;
11741199 self . word_space ( "=" ) ;
1175- let npals = || parser:: needs_par_as_let_scrutinee ( expr. precedence ( ) . order ( ) ) ;
1176- self . print_expr_cond_paren ( expr, Self :: cond_needs_par ( expr) || npals ( ) )
1200+ self . print_expr_cond_paren (
1201+ expr,
1202+ fixup. parenthesize_exterior_struct_lit && parser:: contains_exterior_struct_lit ( expr)
1203+ || parser:: needs_par_as_let_scrutinee ( expr. precedence ( ) . order ( ) ) ,
1204+ FixupContext :: default ( ) ,
1205+ ) ;
11771206 }
11781207
11791208 fn print_mac ( & mut self , m : & ast:: MacCall ) {
@@ -1220,7 +1249,7 @@ impl<'a> State<'a> {
12201249 print_reg_or_class ( s, reg) ;
12211250 s. pclose ( ) ;
12221251 s. space ( ) ;
1223- s. print_expr ( expr) ;
1252+ s. print_expr ( expr, FixupContext :: default ( ) ) ;
12241253 }
12251254 InlineAsmOperand :: Out { reg, late, expr } => {
12261255 s. word ( if * late { "lateout" } else { "out" } ) ;
@@ -1229,7 +1258,7 @@ impl<'a> State<'a> {
12291258 s. pclose ( ) ;
12301259 s. space ( ) ;
12311260 match expr {
1232- Some ( expr) => s. print_expr ( expr) ,
1261+ Some ( expr) => s. print_expr ( expr, FixupContext :: default ( ) ) ,
12331262 None => s. word ( "_" ) ,
12341263 }
12351264 }
@@ -1239,26 +1268,26 @@ impl<'a> State<'a> {
12391268 print_reg_or_class ( s, reg) ;
12401269 s. pclose ( ) ;
12411270 s. space ( ) ;
1242- s. print_expr ( expr) ;
1271+ s. print_expr ( expr, FixupContext :: default ( ) ) ;
12431272 }
12441273 InlineAsmOperand :: SplitInOut { reg, late, in_expr, out_expr } => {
12451274 s. word ( if * late { "inlateout" } else { "inout" } ) ;
12461275 s. popen ( ) ;
12471276 print_reg_or_class ( s, reg) ;
12481277 s. pclose ( ) ;
12491278 s. space ( ) ;
1250- s. print_expr ( in_expr) ;
1279+ s. print_expr ( in_expr, FixupContext :: default ( ) ) ;
12511280 s. space ( ) ;
12521281 s. word_space ( "=>" ) ;
12531282 match out_expr {
1254- Some ( out_expr) => s. print_expr ( out_expr) ,
1283+ Some ( out_expr) => s. print_expr ( out_expr, FixupContext :: default ( ) ) ,
12551284 None => s. word ( "_" ) ,
12561285 }
12571286 }
12581287 InlineAsmOperand :: Const { anon_const } => {
12591288 s. word ( "const" ) ;
12601289 s. space ( ) ;
1261- s. print_expr ( & anon_const. value ) ;
1290+ s. print_expr ( & anon_const. value , FixupContext :: default ( ) ) ;
12621291 }
12631292 InlineAsmOperand :: Sym { sym } => {
12641293 s. word ( "sym" ) ;
@@ -1452,18 +1481,18 @@ impl<'a> State<'a> {
14521481 self . print_pat ( inner) ;
14531482 }
14541483 }
1455- PatKind :: Lit ( e) => self . print_expr ( e) ,
1484+ PatKind :: Lit ( e) => self . print_expr ( e, FixupContext :: default ( ) ) ,
14561485 PatKind :: Range ( begin, end, Spanned { node : end_kind, .. } ) => {
14571486 if let Some ( e) = begin {
1458- self . print_expr ( e) ;
1487+ self . print_expr ( e, FixupContext :: default ( ) ) ;
14591488 }
14601489 match end_kind {
14611490 RangeEnd :: Included ( RangeSyntax :: DotDotDot ) => self . word ( "..." ) ,
14621491 RangeEnd :: Included ( RangeSyntax :: DotDotEq ) => self . word ( "..=" ) ,
14631492 RangeEnd :: Excluded => self . word ( ".." ) ,
14641493 }
14651494 if let Some ( e) = end {
1466- self . print_expr ( e) ;
1495+ self . print_expr ( e, FixupContext :: default ( ) ) ;
14671496 }
14681497 }
14691498 PatKind :: Slice ( elts) => {
@@ -1617,7 +1646,7 @@ impl<'a> State<'a> {
16171646 if let Some ( default) = default {
16181647 s. space ( ) ;
16191648 s. word_space ( "=" ) ;
1620- s. print_expr ( & default. value ) ;
1649+ s. print_expr ( & default. value , FixupContext :: default ( ) ) ;
16211650 }
16221651 }
16231652 }
0 commit comments