@@ -50,6 +50,18 @@ pub enum ExprType {
50
50
SubExpression ,
51
51
}
52
52
53
+ fn is_nested_binary ( context : & RewriteContext , expr : & ast:: Expr ) -> bool {
54
+ if let ast:: ExprKind :: Binary ( op, ..) = expr. node {
55
+ if let Some ( upper_op) = * context. upper_binop . borrow ( ) {
56
+ op. node == upper_op
57
+ } else {
58
+ false
59
+ }
60
+ } else {
61
+ false
62
+ }
63
+ }
64
+
53
65
pub fn format_expr (
54
66
expr : & ast:: Expr ,
55
67
expr_type : ExprType ,
@@ -62,6 +74,9 @@ pub fn format_expr(
62
74
return Some ( context. snippet ( expr. span ( ) ) . to_owned ( ) ) ;
63
75
}
64
76
77
+ let is_nested_binary = is_nested_binary ( context, expr) ;
78
+ context. set_upper_binop ( expr) ;
79
+
65
80
let expr_rw = match expr. node {
66
81
ast:: ExprKind :: Array ( ref expr_vec) => rewrite_array (
67
82
& ptr_vec_to_ref_vec ( expr_vec) ,
@@ -89,6 +104,7 @@ pub fn format_expr(
89
104
context,
90
105
shape,
91
106
context. config . binop_separator ( ) ,
107
+ is_nested_binary,
92
108
)
93
109
}
94
110
ast:: ExprKind :: Unary ( ref op, ref subexpr) => rewrite_unary_op ( context, op, subexpr, shape) ,
@@ -201,6 +217,7 @@ pub fn format_expr(
201
217
context,
202
218
shape,
203
219
SeparatorPlace :: Front ,
220
+ false ,
204
221
) ,
205
222
ast:: ExprKind :: Type ( ref expr, ref ty) => rewrite_pair (
206
223
& * * expr,
@@ -209,6 +226,7 @@ pub fn format_expr(
209
226
context,
210
227
shape,
211
228
SeparatorPlace :: Back ,
229
+ false ,
212
230
) ,
213
231
ast:: ExprKind :: Index ( ref expr, ref index) => {
214
232
rewrite_index ( & * * expr, & * * index, context, shape)
@@ -226,6 +244,7 @@ pub fn format_expr(
226
244
context,
227
245
shape,
228
246
SeparatorPlace :: Back ,
247
+ false ,
229
248
)
230
249
}
231
250
ast:: ExprKind :: Range ( ref lhs, ref rhs, limits) => {
@@ -262,6 +281,7 @@ pub fn format_expr(
262
281
context,
263
282
shape,
264
283
context. config . binop_separator ( ) ,
284
+ false ,
265
285
)
266
286
}
267
287
( None , Some ( rhs) ) => {
@@ -323,17 +343,34 @@ pub struct PairParts<'a> {
323
343
suffix : & ' a str ,
324
344
}
325
345
346
+ /// Returns true if the given expression is a chain with 0 or more prefixes or
347
+ /// suffixes (e.g. `&x.y`, `x.y.z()?` or `x.0 as usize`).
348
+ fn is_chain ( expr : & ast:: Expr ) -> bool {
349
+ match expr. node {
350
+ ast:: ExprKind :: AddrOf ( _, ref expr)
351
+ | ast:: ExprKind :: Box ( ref expr)
352
+ | ast:: ExprKind :: Try ( ref expr)
353
+ | ast:: ExprKind :: Unary ( _, ref expr)
354
+ | ast:: ExprKind :: Cast ( ref expr, _) => is_chain ( expr) ,
355
+ ast:: ExprKind :: MethodCall ( ..) | ast:: ExprKind :: Field ( ..) | ast:: ExprKind :: TupField ( ..) => {
356
+ true
357
+ }
358
+ _ => false ,
359
+ }
360
+ }
361
+
326
362
pub fn rewrite_pair < LHS , RHS > (
327
363
lhs : & LHS ,
328
364
rhs : & RHS ,
329
365
pp : PairParts ,
330
366
context : & RewriteContext ,
331
367
shape : Shape ,
332
368
separator_place : SeparatorPlace ,
369
+ is_nested_binary : bool ,
333
370
) -> Option < String >
334
371
where
335
372
LHS : Rewrite ,
336
- RHS : Rewrite ,
373
+ RHS : ToExpr + Rewrite ,
337
374
{
338
375
let lhs_overhead = match separator_place {
339
376
SeparatorPlace :: Back => shape. used_width ( ) + pp. prefix . len ( ) + pp. infix . trim_right ( ) . len ( ) ,
@@ -392,6 +429,20 @@ where
392
429
rhs_shape = rhs_shape. offset_left ( infix. len ( ) ) ?;
393
430
}
394
431
let rhs_result = rhs. rewrite ( context, rhs_shape) ?;
432
+ // Put the rhs on the same line as the lhs if:
433
+ // 1. it is not inside the other binary expression
434
+ // 2. the lhs fits in a single line
435
+ // 3. putting the rhs on the next line needs multiple lines as well
436
+ if !is_nested_binary && !lhs_result. contains ( '\n' ) && rhs_result. contains ( '\n' ) {
437
+ if let Some ( ref orig_rhs_result) = rhs_orig_result {
438
+ if rhs. to_expr ( ) . map_or ( false , is_chain) {
439
+ return Some ( format ! (
440
+ "{}{}{}{}" ,
441
+ lhs_result, pp. infix, orig_rhs_result, pp. suffix
442
+ ) ) ;
443
+ }
444
+ }
445
+ }
395
446
let indent_str = rhs_shape. indent . to_string_with_newline ( context. config ) ;
396
447
let infix_with_sep = match separator_place {
397
448
SeparatorPlace :: Back => format ! ( "{}{}" , infix, indent_str) ,
0 commit comments