Handle special-case macros
This commit is contained in:
parent
ffbe52eb76
commit
0f5dcc665d
95
src/expr.rs
95
src/expr.rs
@ -1862,9 +1862,6 @@ pub fn rewrite_call_inner<'a, T>(
|
||||
};
|
||||
let used_width = extra_offset(callee_str, shape);
|
||||
let one_line_width = shape.width.checked_sub(used_width + 2 * paren_overhead)?;
|
||||
// 1 = "("
|
||||
let combine_arg_with_callee =
|
||||
callee_str.len() + 1 <= context.config.tab_spaces() && args.len() == 1;
|
||||
|
||||
// 1 = "(" or ")"
|
||||
let one_line_shape = shape
|
||||
@ -1889,7 +1886,7 @@ pub fn rewrite_call_inner<'a, T>(
|
||||
one_line_width,
|
||||
args_max_width,
|
||||
force_trailing_comma,
|
||||
combine_arg_with_callee,
|
||||
callee_str,
|
||||
)?;
|
||||
|
||||
if !context.use_block_indent() && need_block_indent(&list_str, nested_shape) && !extendable {
|
||||
@ -1930,7 +1927,7 @@ fn rewrite_call_args<'a, T>(
|
||||
one_line_width: usize,
|
||||
args_max_width: usize,
|
||||
force_trailing_comma: bool,
|
||||
combine_arg_with_callee: bool,
|
||||
callee_str: &str,
|
||||
) -> Option<(bool, String)>
|
||||
where
|
||||
T: Rewrite + Spanned + ToExpr + 'a,
|
||||
@ -1960,7 +1957,7 @@ fn rewrite_call_args<'a, T>(
|
||||
nested_shape,
|
||||
one_line_width,
|
||||
args_max_width,
|
||||
combine_arg_with_callee,
|
||||
callee_str,
|
||||
);
|
||||
|
||||
let fmt = ListFormatting {
|
||||
@ -1980,7 +1977,8 @@ fn rewrite_call_args<'a, T>(
|
||||
config: context.config,
|
||||
};
|
||||
|
||||
write_list(&item_vec, &fmt).map(|args_str| (tactic != DefinitiveListTactic::Vertical, args_str))
|
||||
write_list(&item_vec, &fmt)
|
||||
.map(|args_str| (tactic == DefinitiveListTactic::Horizontal, args_str))
|
||||
}
|
||||
|
||||
fn try_overflow_last_arg<'a, T>(
|
||||
@ -1991,11 +1989,14 @@ fn try_overflow_last_arg<'a, T>(
|
||||
nested_shape: Shape,
|
||||
one_line_width: usize,
|
||||
args_max_width: usize,
|
||||
combine_arg_with_callee: bool,
|
||||
callee_str: &str,
|
||||
) -> DefinitiveListTactic
|
||||
where
|
||||
T: Rewrite + Spanned + ToExpr + 'a,
|
||||
{
|
||||
// 1 = "("
|
||||
let combine_arg_with_callee =
|
||||
callee_str.len() + 1 <= context.config.tab_spaces() && args.len() == 1;
|
||||
let overflow_last = combine_arg_with_callee || can_be_overflowed(context, args);
|
||||
|
||||
// Replace the last item with its first line to see if it fits with
|
||||
@ -2032,6 +2033,16 @@ fn try_overflow_last_arg<'a, T>(
|
||||
_ if args.len() >= 1 => {
|
||||
item_vec[args.len() - 1].item = args.last()
|
||||
.and_then(|last_arg| last_arg.rewrite(context, nested_shape));
|
||||
|
||||
let default_tactic = || {
|
||||
definitive_tactic(
|
||||
&*item_vec,
|
||||
ListTactic::LimitedHorizontalVertical(args_max_width),
|
||||
Separator::Comma,
|
||||
one_line_width,
|
||||
)
|
||||
};
|
||||
|
||||
// Use horizontal layout for a function with a single argument as long as
|
||||
// everything fits in a single line.
|
||||
if args.len() == 1
|
||||
@ -2042,12 +2053,44 @@ fn try_overflow_last_arg<'a, T>(
|
||||
{
|
||||
tactic = DefinitiveListTactic::Horizontal;
|
||||
} else {
|
||||
tactic = definitive_tactic(
|
||||
&*item_vec,
|
||||
ListTactic::LimitedHorizontalVertical(args_max_width),
|
||||
Separator::Comma,
|
||||
one_line_width,
|
||||
);
|
||||
tactic = default_tactic();
|
||||
let is_simple_enough =
|
||||
tactic == DefinitiveListTactic::Vertical && is_every_args_simple(args);
|
||||
if is_simple_enough
|
||||
&& FORMAT_LIKE_WHITELIST
|
||||
.iter()
|
||||
.find(|s| **s == callee_str)
|
||||
.is_some()
|
||||
{
|
||||
let args_tactic = definitive_tactic(
|
||||
&item_vec[1..],
|
||||
ListTactic::HorizontalVertical,
|
||||
Separator::Comma,
|
||||
nested_shape.width,
|
||||
);
|
||||
tactic = if args_tactic == DefinitiveListTactic::Horizontal {
|
||||
DefinitiveListTactic::FormatCall
|
||||
} else {
|
||||
default_tactic()
|
||||
};
|
||||
} else if is_simple_enough && item_vec.len() >= 2
|
||||
&& WRITE_LIKE_WHITELIST
|
||||
.iter()
|
||||
.find(|s| **s == callee_str)
|
||||
.is_some()
|
||||
{
|
||||
let args_tactic = definitive_tactic(
|
||||
&item_vec[2..],
|
||||
ListTactic::HorizontalVertical,
|
||||
Separator::Comma,
|
||||
nested_shape.width,
|
||||
);
|
||||
tactic = if args_tactic == DefinitiveListTactic::Horizontal {
|
||||
DefinitiveListTactic::WriteCall
|
||||
} else {
|
||||
default_tactic()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -2056,6 +2099,30 @@ fn try_overflow_last_arg<'a, T>(
|
||||
tactic
|
||||
}
|
||||
|
||||
fn is_simple_arg(expr: &ast::Expr) -> bool {
|
||||
match expr.node {
|
||||
ast::ExprKind::Lit(..) => true,
|
||||
ast::ExprKind::Path(ref qself, ref path) => qself.is_none() && path.segments.len() <= 1,
|
||||
ast::ExprKind::AddrOf(_, ref expr)
|
||||
| ast::ExprKind::Box(ref expr)
|
||||
| ast::ExprKind::Cast(ref expr, _)
|
||||
| ast::ExprKind::Field(ref expr, _)
|
||||
| ast::ExprKind::Try(ref expr)
|
||||
| ast::ExprKind::TupField(ref expr, _)
|
||||
| ast::ExprKind::Unary(_, ref expr) => is_simple_arg(expr),
|
||||
ast::ExprKind::Index(ref lhs, ref rhs) | ast::ExprKind::Repeat(ref lhs, ref rhs) => {
|
||||
is_simple_arg(lhs) && is_simple_arg(rhs)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_every_args_simple<T: ToExpr>(lists: &[&T]) -> bool {
|
||||
lists
|
||||
.iter()
|
||||
.all(|arg| arg.to_expr().map_or(false, is_simple_arg))
|
||||
}
|
||||
|
||||
/// Returns a shape for the last argument which is going to be overflowed.
|
||||
fn last_arg_shape<T>(
|
||||
lists: &[&T],
|
||||
|
28
src/lists.rs
28
src/lists.rs
@ -160,6 +160,10 @@ pub enum DefinitiveListTactic {
|
||||
Vertical,
|
||||
Horizontal,
|
||||
Mixed,
|
||||
// Special case tactic for `format!()` variants.
|
||||
FormatCall,
|
||||
// Special case tactic for `write!()` varianta.
|
||||
WriteCall,
|
||||
}
|
||||
|
||||
impl DefinitiveListTactic {
|
||||
@ -267,7 +271,7 @@ pub fn write_list<I, T>(items: I, formatting: &ListFormatting) -> Option<String>
|
||||
I: IntoIterator<Item = T> + Clone,
|
||||
T: AsRef<ListItem>,
|
||||
{
|
||||
let tactic = formatting.tactic;
|
||||
let mut tactic = formatting.tactic;
|
||||
let sep_len = formatting.separator.len();
|
||||
|
||||
// Now that we know how we will layout, we can decide for sure if there
|
||||
@ -309,6 +313,28 @@ pub fn write_list<I, T>(items: I, formatting: &ListFormatting) -> Option<String>
|
||||
DefinitiveListTactic::Horizontal if !first => {
|
||||
result.push(' ');
|
||||
}
|
||||
DefinitiveListTactic::FormatCall if !first => {
|
||||
result.push('\n');
|
||||
result.push_str(indent_str);
|
||||
tactic = DefinitiveListTactic::Horizontal;
|
||||
}
|
||||
DefinitiveListTactic::WriteCall => {
|
||||
let second = i == 1;
|
||||
let third = i == 2;
|
||||
|
||||
if first {
|
||||
// Nothing
|
||||
} else if second {
|
||||
result.push('\n');
|
||||
result.push_str(indent_str);
|
||||
} else if third {
|
||||
result.push('\n');
|
||||
result.push_str(indent_str);
|
||||
tactic = DefinitiveListTactic::Horizontal;
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
DefinitiveListTactic::Vertical if !first => {
|
||||
result.push('\n');
|
||||
result.push_str(indent_str);
|
||||
|
Loading…
Reference in New Issue
Block a user