@@ -7,6 +7,7 @@ mod item;
7
7
8
8
use crate :: pp:: Breaks :: { Consistent , Inconsistent } ;
9
9
use crate :: pp:: { self , Breaks } ;
10
+ use crate :: pprust:: state:: expr:: FixupContext ;
10
11
use rustc_ast:: attr:: AttrIdGenerator ;
11
12
use rustc_ast:: ptr:: P ;
12
13
use rustc_ast:: token:: { self , BinOpToken , CommentKind , Delimiter , Nonterminal , Token , TokenKind } ;
@@ -798,7 +799,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
798
799
}
799
800
800
801
fn expr_to_string ( & self , e : & ast:: Expr ) -> String {
801
- Self :: to_string ( |s| s. print_expr ( e) )
802
+ Self :: to_string ( |s| s. print_expr ( e, FixupContext :: default ( ) ) )
802
803
}
803
804
804
805
fn meta_item_lit_to_string ( & self , lit : & ast:: MetaItemLit ) -> String {
@@ -903,7 +904,7 @@ impl<'a> State<'a> {
903
904
}
904
905
905
906
fn commasep_exprs ( & mut self , b : Breaks , exprs : & [ P < ast:: Expr > ] ) {
906
- self . commasep_cmnt ( b, exprs, |s, e| s. print_expr ( e) , |e| e. span )
907
+ self . commasep_cmnt ( b, exprs, |s, e| s. print_expr ( e, FixupContext :: default ( ) ) , |e| e. span )
907
908
}
908
909
909
910
pub fn print_opt_lifetime ( & mut self , lifetime : & Option < ast:: Lifetime > ) {
@@ -940,7 +941,7 @@ impl<'a> State<'a> {
940
941
match generic_arg {
941
942
GenericArg :: Lifetime ( lt) => self . print_lifetime ( * lt) ,
942
943
GenericArg :: Type ( ty) => self . print_type ( ty) ,
943
- GenericArg :: Const ( ct) => self . print_expr ( & ct. value ) ,
944
+ GenericArg :: Const ( ct) => self . print_expr ( & ct. value , FixupContext :: default ( ) ) ,
944
945
}
945
946
}
946
947
@@ -1007,12 +1008,12 @@ impl<'a> State<'a> {
1007
1008
self . word ( "[" ) ;
1008
1009
self . print_type ( ty) ;
1009
1010
self . word ( "; " ) ;
1010
- self . print_expr ( & length. value ) ;
1011
+ self . print_expr ( & length. value , FixupContext :: default ( ) ) ;
1011
1012
self . word ( "]" ) ;
1012
1013
}
1013
1014
ast:: TyKind :: Typeof ( e) => {
1014
1015
self . word ( "typeof(" ) ;
1015
- self . print_expr ( & e. value ) ;
1016
+ self . print_expr ( & e. value , FixupContext :: default ( ) ) ;
1016
1017
self . word ( ")" ) ;
1017
1018
}
1018
1019
ast:: TyKind :: Infer => {
@@ -1068,7 +1069,7 @@ impl<'a> State<'a> {
1068
1069
if let Some ( ( init, els) ) = loc. kind . init_else_opt ( ) {
1069
1070
self . nbsp ( ) ;
1070
1071
self . word_space ( "=" ) ;
1071
- self . print_expr ( init) ;
1072
+ self . print_expr ( init, FixupContext :: default ( ) ) ;
1072
1073
if let Some ( els) = els {
1073
1074
self . cbox ( INDENT_UNIT ) ;
1074
1075
self . ibox ( INDENT_UNIT ) ;
@@ -1082,14 +1083,14 @@ impl<'a> State<'a> {
1082
1083
ast:: StmtKind :: Item ( item) => self . print_item ( item) ,
1083
1084
ast:: StmtKind :: Expr ( expr) => {
1084
1085
self . space_if_not_bol ( ) ;
1085
- self . print_expr_outer_attr_style ( expr, false ) ;
1086
+ self . print_expr_outer_attr_style ( expr, false , FixupContext :: default ( ) ) ;
1086
1087
if classify:: expr_requires_semi_to_be_stmt ( expr) {
1087
1088
self . word ( ";" ) ;
1088
1089
}
1089
1090
}
1090
1091
ast:: StmtKind :: Semi ( expr) => {
1091
1092
self . space_if_not_bol ( ) ;
1092
- self . print_expr_outer_attr_style ( expr, false ) ;
1093
+ self . print_expr_outer_attr_style ( expr, false , FixupContext :: default ( ) ) ;
1093
1094
self . word ( ";" ) ;
1094
1095
}
1095
1096
ast:: StmtKind :: Empty => {
@@ -1141,7 +1142,7 @@ impl<'a> State<'a> {
1141
1142
ast:: StmtKind :: Expr ( expr) if i == blk. stmts . len ( ) - 1 => {
1142
1143
self . maybe_print_comment ( st. span . lo ( ) ) ;
1143
1144
self . space_if_not_bol ( ) ;
1144
- self . print_expr_outer_attr_style ( expr, false ) ;
1145
+ self . print_expr_outer_attr_style ( expr, false , FixupContext :: default ( ) ) ;
1145
1146
self . maybe_print_trailing_comment ( expr. span , Some ( blk. span . hi ( ) ) ) ;
1146
1147
}
1147
1148
_ => self . print_stmt ( st) ,
@@ -1154,15 +1155,40 @@ impl<'a> State<'a> {
1154
1155
}
1155
1156
1156
1157
/// Print a `let pat = expr` expression.
1157
- fn print_let ( & mut self , pat : & ast:: Pat , expr : & ast:: Expr ) {
1158
+ ///
1159
+ /// Parentheses are inserted surrounding `expr` if a round-trip through the
1160
+ /// parser would otherwise work out the wrong way in a condition position.
1161
+ ///
1162
+ /// For example each of the following would mean the wrong thing without
1163
+ /// parentheses.
1164
+ ///
1165
+ /// ```ignore
1166
+ /// if let _ = (Struct {}) {}
1167
+ ///
1168
+ /// if let _ = (true && false) {}
1169
+ /// ```
1170
+ ///
1171
+ /// In a match guard, the second case still requires parens, but the first
1172
+ /// case no longer does because anything until `=>` is considered part of
1173
+ /// the match guard expression. Parsing of the expression is not terminated
1174
+ /// by `{` in that position.
1175
+ ///
1176
+ /// ```ignore
1177
+ /// match () {
1178
+ /// () if let _ = Struct {} => {}
1179
+ /// () if let _ = (true && false) => {}
1180
+ /// }
1181
+ /// ```
1182
+ fn print_let ( & mut self , pat : & ast:: Pat , expr : & ast:: Expr , fixup : FixupContext ) {
1158
1183
self . word ( "let " ) ;
1159
1184
self . print_pat ( pat) ;
1160
1185
self . space ( ) ;
1161
1186
self . word_space ( "=" ) ;
1162
1187
self . print_expr_cond_paren (
1163
1188
expr,
1164
- parser:: contains_exterior_struct_lit ( expr)
1189
+ fixup . parenthesize_exterior_struct_lit && parser:: contains_exterior_struct_lit ( expr)
1165
1190
|| parser:: needs_par_as_let_scrutinee ( expr. precedence ( ) . order ( ) ) ,
1191
+ FixupContext :: default ( ) ,
1166
1192
) ;
1167
1193
}
1168
1194
@@ -1210,7 +1236,7 @@ impl<'a> State<'a> {
1210
1236
print_reg_or_class ( s, reg) ;
1211
1237
s. pclose ( ) ;
1212
1238
s. space ( ) ;
1213
- s. print_expr ( expr) ;
1239
+ s. print_expr ( expr, FixupContext :: default ( ) ) ;
1214
1240
}
1215
1241
InlineAsmOperand :: Out { reg, late, expr } => {
1216
1242
s. word ( if * late { "lateout" } else { "out" } ) ;
@@ -1219,7 +1245,7 @@ impl<'a> State<'a> {
1219
1245
s. pclose ( ) ;
1220
1246
s. space ( ) ;
1221
1247
match expr {
1222
- Some ( expr) => s. print_expr ( expr) ,
1248
+ Some ( expr) => s. print_expr ( expr, FixupContext :: default ( ) ) ,
1223
1249
None => s. word ( "_" ) ,
1224
1250
}
1225
1251
}
@@ -1229,26 +1255,26 @@ impl<'a> State<'a> {
1229
1255
print_reg_or_class ( s, reg) ;
1230
1256
s. pclose ( ) ;
1231
1257
s. space ( ) ;
1232
- s. print_expr ( expr) ;
1258
+ s. print_expr ( expr, FixupContext :: default ( ) ) ;
1233
1259
}
1234
1260
InlineAsmOperand :: SplitInOut { reg, late, in_expr, out_expr } => {
1235
1261
s. word ( if * late { "inlateout" } else { "inout" } ) ;
1236
1262
s. popen ( ) ;
1237
1263
print_reg_or_class ( s, reg) ;
1238
1264
s. pclose ( ) ;
1239
1265
s. space ( ) ;
1240
- s. print_expr ( in_expr) ;
1266
+ s. print_expr ( in_expr, FixupContext :: default ( ) ) ;
1241
1267
s. space ( ) ;
1242
1268
s. word_space ( "=>" ) ;
1243
1269
match out_expr {
1244
- Some ( out_expr) => s. print_expr ( out_expr) ,
1270
+ Some ( out_expr) => s. print_expr ( out_expr, FixupContext :: default ( ) ) ,
1245
1271
None => s. word ( "_" ) ,
1246
1272
}
1247
1273
}
1248
1274
InlineAsmOperand :: Const { anon_const } => {
1249
1275
s. word ( "const" ) ;
1250
1276
s. space ( ) ;
1251
- s. print_expr ( & anon_const. value ) ;
1277
+ s. print_expr ( & anon_const. value , FixupContext :: default ( ) ) ;
1252
1278
}
1253
1279
InlineAsmOperand :: Sym { sym } => {
1254
1280
s. word ( "sym" ) ;
@@ -1442,18 +1468,18 @@ impl<'a> State<'a> {
1442
1468
self . print_pat ( inner) ;
1443
1469
}
1444
1470
}
1445
- PatKind :: Lit ( e) => self . print_expr ( e) ,
1471
+ PatKind :: Lit ( e) => self . print_expr ( e, FixupContext :: default ( ) ) ,
1446
1472
PatKind :: Range ( begin, end, Spanned { node : end_kind, .. } ) => {
1447
1473
if let Some ( e) = begin {
1448
- self . print_expr ( e) ;
1474
+ self . print_expr ( e, FixupContext :: default ( ) ) ;
1449
1475
}
1450
1476
match end_kind {
1451
1477
RangeEnd :: Included ( RangeSyntax :: DotDotDot ) => self . word ( "..." ) ,
1452
1478
RangeEnd :: Included ( RangeSyntax :: DotDotEq ) => self . word ( "..=" ) ,
1453
1479
RangeEnd :: Excluded => self . word ( ".." ) ,
1454
1480
}
1455
1481
if let Some ( e) = end {
1456
- self . print_expr ( e) ;
1482
+ self . print_expr ( e, FixupContext :: default ( ) ) ;
1457
1483
}
1458
1484
}
1459
1485
PatKind :: Slice ( elts) => {
@@ -1607,7 +1633,7 @@ impl<'a> State<'a> {
1607
1633
if let Some ( default) = default {
1608
1634
s. space ( ) ;
1609
1635
s. word_space ( "=" ) ;
1610
- s. print_expr ( & default. value ) ;
1636
+ s. print_expr ( & default. value , FixupContext :: default ( ) ) ;
1611
1637
}
1612
1638
}
1613
1639
}
0 commit comments