diff --git a/src/config/mod.rs b/src/config/mod.rs index c3b998d0211e..84d94fada776 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -88,8 +88,10 @@ create_config! { // Misc. remove_nested_parens: bool, true, true, "Remove nested parens"; combine_control_expr: bool, true, false, "Combine control expressions with function calls"; - struct_field_align_threshold: usize, 0, false, "Align struct fields if their diffs fits within \ - threshold"; + overflow_delimited_expr: bool, false, false, + "Allow trailing bracket/brace delimited expressions to overflow"; + struct_field_align_threshold: usize, 0, false, + "Align struct fields if their diffs fits within threshold"; enum_discrim_align_threshold: usize, 0, false, "Align enum variants discrims, if their diffs fit within threshold"; match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \ diff --git a/src/expr.rs b/src/expr.rs index 08b9ad3079c7..502c42ff213f 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1343,12 +1343,31 @@ pub fn can_be_overflowed_expr(context: &RewriteContext, expr: &ast::Expr, args_l ast::ExprKind::Block(..) | ast::ExprKind::Closure(..) => { context.use_block_indent() || context.config.indent_style() == IndentStyle::Visual } - ast::ExprKind::Array(..) - | ast::ExprKind::Call(..) - | ast::ExprKind::Mac(..) - | ast::ExprKind::MethodCall(..) - | ast::ExprKind::Struct(..) - | ast::ExprKind::Tup(..) => context.use_block_indent() && args_len == 1, + + // Handle `[]` and `{}`-like expressions + ast::ExprKind::Array(..) | ast::ExprKind::Struct(..) => { + if context.config.overflow_delimited_expr() { + context.use_block_indent() || context.config.indent_style() == IndentStyle::Visual + } else { + context.use_block_indent() && args_len == 1 + } + } + ast::ExprKind::Mac(ref macro_) => { + match (macro_.node.delim, context.config.overflow_delimited_expr()) { + (ast::MacDelimiter::Bracket, true) | (ast::MacDelimiter::Brace, true) => { + context.use_block_indent() + || context.config.indent_style() == IndentStyle::Visual + } + _ => context.use_block_indent() && args_len == 1, + } + } + + // Handle parenthetical expressions + ast::ExprKind::Call(..) | ast::ExprKind::MethodCall(..) | ast::ExprKind::Tup(..) => { + context.use_block_indent() && args_len == 1 + } + + // Handle unary-like expressions ast::ExprKind::AddrOf(_, ref expr) | ast::ExprKind::Box(ref expr) | ast::ExprKind::Try(ref expr) diff --git a/src/overflow.rs b/src/overflow.rs index 31cd1b054662..4a583fc1de83 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -404,6 +404,7 @@ impl<'a> Context<'a> { closures::rewrite_last_closure(self.context, expr, shape) } } + // When overflowing the expressions which consists of a control flow // expression, avoid condition to use multi line. ast::ExprKind::If(..) @@ -422,6 +423,7 @@ impl<'a> Context<'a> { expr.rewrite(self.context, shape) } } + _ => expr.rewrite(self.context, shape), } } diff --git a/tests/source/expr-overflow-delimited.rs b/tests/source/expr-overflow-delimited.rs new file mode 100644 index 000000000000..5a3d1671f2c2 --- /dev/null +++ b/tests/source/expr-overflow-delimited.rs @@ -0,0 +1,111 @@ +// rustfmt-overflow_delimited_expr: true + +fn combine_blocklike() { + do_thing( + |param| { + action(); + foo(param) + }, + ); + + do_thing( + x, + |param| { + action(); + foo(param) + }, + ); + + do_thing( + Bar { + x: value, + y: value2, + }, + ); + + do_thing( + x, + Bar { + x: value, + y: value2, + }, + ); + + do_thing( + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ], + ); + + do_thing( + x, + ( + 1, + 2, + 3, + |param| { + action(); + foo(param) + }, + ), + ); +} + +fn combine_struct_sample() { + let identity = verify( + &ctx, + VerifyLogin { + type_: LoginType::Username, + username: args.username.clone(), + password: Some(args.password.clone()), + domain: None, + }, + )?; +} + +fn combine_macro_sample() { + rocket::ignite() + .mount( + "/", + routes![ + http::auth::login, + http::auth::logout, + http::cors::options, + http::action::dance, + http::action::sleep, + ], + ) + .launch(); +} diff --git a/tests/target/expr-overflow-delimited.rs b/tests/target/expr-overflow-delimited.rs new file mode 100644 index 000000000000..440b149997ea --- /dev/null +++ b/tests/target/expr-overflow-delimited.rs @@ -0,0 +1,80 @@ +// rustfmt-overflow_delimited_expr: true + +fn combine_blocklike() { + do_thing(|param| { + action(); + foo(param) + }); + + do_thing(x, |param| { + action(); + foo(param) + }); + + do_thing(Bar { + x: value, + y: value2, + }); + + do_thing(x, Bar { + x: value, + y: value2, + }); + + do_thing(&[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing(x, &[ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing(vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing(x, vec![ + value_with_longer_name, + value2_with_longer_name, + value3_with_longer_name, + value4_with_longer_name, + ]); + + do_thing( + x, + (1, 2, 3, |param| { + action(); + foo(param) + }), + ); +} + +fn combine_struct_sample() { + let identity = verify(&ctx, VerifyLogin { + type_: LoginType::Username, + username: args.username.clone(), + password: Some(args.password.clone()), + domain: None, + })?; +} + +fn combine_macro_sample() { + rocket::ignite() + .mount("/", routes![ + http::auth::login, + http::auth::logout, + http::cors::options, + http::action::dance, + http::action::sleep, + ]) + .launch(); +}