@@ -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 } ;
@@ -811,7 +812,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
811
812
}
812
813
813
814
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 ( ) ) )
815
816
}
816
817
817
818
fn meta_item_lit_to_string ( & self , lit : & ast:: MetaItemLit ) -> String {
@@ -916,7 +917,7 @@ impl<'a> State<'a> {
916
917
}
917
918
918
919
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 )
920
921
}
921
922
922
923
pub fn print_opt_lifetime ( & mut self , lifetime : & Option < ast:: Lifetime > ) {
@@ -953,7 +954,7 @@ impl<'a> State<'a> {
953
954
match generic_arg {
954
955
GenericArg :: Lifetime ( lt) => self . print_lifetime ( * lt) ,
955
956
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 ( ) ) ,
957
958
}
958
959
}
959
960
@@ -1020,12 +1021,12 @@ impl<'a> State<'a> {
1020
1021
self . word ( "[" ) ;
1021
1022
self . print_type ( ty) ;
1022
1023
self . word ( "; " ) ;
1023
- self . print_expr ( & length. value ) ;
1024
+ self . print_expr ( & length. value , FixupContext :: default ( ) ) ;
1024
1025
self . word ( "]" ) ;
1025
1026
}
1026
1027
ast:: TyKind :: Typeof ( e) => {
1027
1028
self . word ( "typeof(" ) ;
1028
- self . print_expr ( & e. value ) ;
1029
+ self . print_expr ( & e. value , FixupContext :: default ( ) ) ;
1029
1030
self . word ( ")" ) ;
1030
1031
}
1031
1032
ast:: TyKind :: Infer => {
@@ -1081,7 +1082,7 @@ impl<'a> State<'a> {
1081
1082
if let Some ( ( init, els) ) = loc. kind . init_else_opt ( ) {
1082
1083
self . nbsp ( ) ;
1083
1084
self . word_space ( "=" ) ;
1084
- self . print_expr ( init) ;
1085
+ self . print_expr ( init, FixupContext :: default ( ) ) ;
1085
1086
if let Some ( els) = els {
1086
1087
self . cbox ( INDENT_UNIT ) ;
1087
1088
self . ibox ( INDENT_UNIT ) ;
@@ -1095,14 +1096,14 @@ impl<'a> State<'a> {
1095
1096
ast:: StmtKind :: Item ( item) => self . print_item ( item) ,
1096
1097
ast:: StmtKind :: Expr ( expr) => {
1097
1098
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 ( ) ) ;
1099
1100
if classify:: expr_requires_semi_to_be_stmt ( expr) {
1100
1101
self . word ( ";" ) ;
1101
1102
}
1102
1103
}
1103
1104
ast:: StmtKind :: Semi ( expr) => {
1104
1105
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 ( ) ) ;
1106
1107
self . word ( ";" ) ;
1107
1108
}
1108
1109
ast:: StmtKind :: Empty => {
@@ -1154,7 +1155,7 @@ impl<'a> State<'a> {
1154
1155
ast:: StmtKind :: Expr ( expr) if i == blk. stmts . len ( ) - 1 => {
1155
1156
self . maybe_print_comment ( st. span . lo ( ) ) ;
1156
1157
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 ( ) ) ;
1158
1159
self . maybe_print_trailing_comment ( expr. span , Some ( blk. span . hi ( ) ) ) ;
1159
1160
}
1160
1161
_ => self . print_stmt ( st) ,
@@ -1167,13 +1168,41 @@ impl<'a> State<'a> {
1167
1168
}
1168
1169
1169
1170
/// 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 ) {
1171
1196
self . word ( "let " ) ;
1172
1197
self . print_pat ( pat) ;
1173
1198
self . space ( ) ;
1174
1199
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
+ ) ;
1177
1206
}
1178
1207
1179
1208
fn print_mac ( & mut self , m : & ast:: MacCall ) {
@@ -1220,7 +1249,7 @@ impl<'a> State<'a> {
1220
1249
print_reg_or_class ( s, reg) ;
1221
1250
s. pclose ( ) ;
1222
1251
s. space ( ) ;
1223
- s. print_expr ( expr) ;
1252
+ s. print_expr ( expr, FixupContext :: default ( ) ) ;
1224
1253
}
1225
1254
InlineAsmOperand :: Out { reg, late, expr } => {
1226
1255
s. word ( if * late { "lateout" } else { "out" } ) ;
@@ -1229,7 +1258,7 @@ impl<'a> State<'a> {
1229
1258
s. pclose ( ) ;
1230
1259
s. space ( ) ;
1231
1260
match expr {
1232
- Some ( expr) => s. print_expr ( expr) ,
1261
+ Some ( expr) => s. print_expr ( expr, FixupContext :: default ( ) ) ,
1233
1262
None => s. word ( "_" ) ,
1234
1263
}
1235
1264
}
@@ -1239,26 +1268,26 @@ impl<'a> State<'a> {
1239
1268
print_reg_or_class ( s, reg) ;
1240
1269
s. pclose ( ) ;
1241
1270
s. space ( ) ;
1242
- s. print_expr ( expr) ;
1271
+ s. print_expr ( expr, FixupContext :: default ( ) ) ;
1243
1272
}
1244
1273
InlineAsmOperand :: SplitInOut { reg, late, in_expr, out_expr } => {
1245
1274
s. word ( if * late { "inlateout" } else { "inout" } ) ;
1246
1275
s. popen ( ) ;
1247
1276
print_reg_or_class ( s, reg) ;
1248
1277
s. pclose ( ) ;
1249
1278
s. space ( ) ;
1250
- s. print_expr ( in_expr) ;
1279
+ s. print_expr ( in_expr, FixupContext :: default ( ) ) ;
1251
1280
s. space ( ) ;
1252
1281
s. word_space ( "=>" ) ;
1253
1282
match out_expr {
1254
- Some ( out_expr) => s. print_expr ( out_expr) ,
1283
+ Some ( out_expr) => s. print_expr ( out_expr, FixupContext :: default ( ) ) ,
1255
1284
None => s. word ( "_" ) ,
1256
1285
}
1257
1286
}
1258
1287
InlineAsmOperand :: Const { anon_const } => {
1259
1288
s. word ( "const" ) ;
1260
1289
s. space ( ) ;
1261
- s. print_expr ( & anon_const. value ) ;
1290
+ s. print_expr ( & anon_const. value , FixupContext :: default ( ) ) ;
1262
1291
}
1263
1292
InlineAsmOperand :: Sym { sym } => {
1264
1293
s. word ( "sym" ) ;
@@ -1452,18 +1481,18 @@ impl<'a> State<'a> {
1452
1481
self . print_pat ( inner) ;
1453
1482
}
1454
1483
}
1455
- PatKind :: Lit ( e) => self . print_expr ( e) ,
1484
+ PatKind :: Lit ( e) => self . print_expr ( e, FixupContext :: default ( ) ) ,
1456
1485
PatKind :: Range ( begin, end, Spanned { node : end_kind, .. } ) => {
1457
1486
if let Some ( e) = begin {
1458
- self . print_expr ( e) ;
1487
+ self . print_expr ( e, FixupContext :: default ( ) ) ;
1459
1488
}
1460
1489
match end_kind {
1461
1490
RangeEnd :: Included ( RangeSyntax :: DotDotDot ) => self . word ( "..." ) ,
1462
1491
RangeEnd :: Included ( RangeSyntax :: DotDotEq ) => self . word ( "..=" ) ,
1463
1492
RangeEnd :: Excluded => self . word ( ".." ) ,
1464
1493
}
1465
1494
if let Some ( e) = end {
1466
- self . print_expr ( e) ;
1495
+ self . print_expr ( e, FixupContext :: default ( ) ) ;
1467
1496
}
1468
1497
}
1469
1498
PatKind :: Slice ( elts) => {
@@ -1617,7 +1646,7 @@ impl<'a> State<'a> {
1617
1646
if let Some ( default) = default {
1618
1647
s. space ( ) ;
1619
1648
s. word_space ( "=" ) ;
1620
- s. print_expr ( & default. value ) ;
1649
+ s. print_expr ( & default. value , FixupContext :: default ( ) ) ;
1621
1650
}
1622
1651
}
1623
1652
}
0 commit comments