Skip to content

Commit cc2c743

Browse files
authored
Merge pull request #2480 from topecongiro/issue-2476
Avoid drifting macro body which is unformattable
2 parents 8531d70 + 9cdac82 commit cc2c743

File tree

7 files changed

+99
-26
lines changed

7 files changed

+99
-26
lines changed

rustfmt-bin/build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ fn main() {
2727
// (git not installed or if this is not a git repository) just return an empty string.
2828
fn commit_info() -> String {
2929
match (channel(), commit_hash(), commit_date()) {
30-
(channel, Some(hash), Some(date)) => format!("{} ({} {})", channel, hash.trim_right(), date),
30+
(channel, Some(hash), Some(date)) => {
31+
format!("{} ({} {})", channel, hash.trim_right(), date)
32+
}
3133
_ => String::new(),
3234
}
3335
}

rustfmt-core/src/expr.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,12 +1908,16 @@ where
19081908
1
19091909
};
19101910
let used_width = extra_offset(callee_str, shape);
1911-
let one_line_width = shape.width.checked_sub(used_width + 2 * paren_overhead)?;
1911+
let one_line_width = shape
1912+
.width
1913+
.checked_sub(used_width + 2 * paren_overhead)
1914+
.unwrap_or(0);
19121915

19131916
// 1 = "(" or ")"
19141917
let one_line_shape = shape
1915-
.offset_left(last_line_width(callee_str) + 1)?
1916-
.sub_width(1)?;
1918+
.offset_left(last_line_width(callee_str) + 1)
1919+
.and_then(|shape| shape.sub_width(1))
1920+
.unwrap_or(Shape { width: 0, ..shape });
19171921
let nested_shape = shape_from_indent_style(
19181922
context,
19191923
shape,
@@ -1950,7 +1954,13 @@ where
19501954
);
19511955
}
19521956

1953-
let args_shape = shape.sub_width(last_line_width(callee_str))?;
1957+
let args_shape = Shape {
1958+
width: shape
1959+
.width
1960+
.checked_sub(last_line_width(callee_str))
1961+
.unwrap_or(0),
1962+
..shape
1963+
};
19541964
Some(format!(
19551965
"{}{}",
19561966
callee_str,
@@ -2317,9 +2327,16 @@ pub fn wrap_args_with_parens(
23172327
shape: Shape,
23182328
nested_shape: Shape,
23192329
) -> String {
2330+
let paren_overhead = paren_overhead(context);
2331+
let fits_one_line = args_str.len() + paren_overhead <= shape.width;
2332+
let extend_width = if args_str.is_empty() {
2333+
paren_overhead
2334+
} else {
2335+
paren_overhead / 2
2336+
};
23202337
if !context.use_block_indent()
2321-
|| (context.inside_macro && !args_str.contains('\n')
2322-
&& args_str.len() + paren_overhead(context) <= shape.width) || is_extendable
2338+
|| (context.inside_macro && !args_str.contains('\n') && fits_one_line)
2339+
|| (is_extendable && extend_width <= shape.width)
23232340
{
23242341
let mut result = String::with_capacity(args_str.len() + 4);
23252342
if context.config.spaces_within_parens_and_brackets() && !args_str.is_empty() {
@@ -2338,8 +2355,10 @@ pub fn wrap_args_with_parens(
23382355
let mut result =
23392356
String::with_capacity(args_str.len() + 2 + indent_str.len() + nested_indent_str.len());
23402357
result.push_str("(");
2341-
result.push_str(&nested_indent_str);
2342-
result.push_str(args_str);
2358+
if !args_str.is_empty() {
2359+
result.push_str(&nested_indent_str);
2360+
result.push_str(args_str);
2361+
}
23432362
result.push_str(&indent_str);
23442363
result.push_str(")");
23452364
result

rustfmt-core/src/macros.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use expr::{rewrite_array, rewrite_call_inner};
3838
use lists::{itemize_list, write_list, ListFormatting};
3939
use rewrite::{Rewrite, RewriteContext};
4040
use shape::{Indent, Shape};
41-
use utils::{format_visibility, mk_sp};
41+
use utils::{format_visibility, mk_sp, wrap_str};
4242

4343
const FORCED_BRACKET_MACROS: &[&str] = &["vec!"];
4444

@@ -810,6 +810,7 @@ impl MacroBranch {
810810
None => return None,
811811
},
812812
};
813+
let new_body = wrap_str(new_body, config.max_width(), shape)?;
813814

814815
// Indent the body since it is in a block.
815816
let indent_str = body_indent.to_string(&config);

rustfmt-core/src/types.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,12 +529,9 @@ impl Rewrite for ast::TyParamBound {
529529
ast::TyParamBound::TraitTyParamBound(ref tref, ast::TraitBoundModifier::None) => {
530530
tref.rewrite(context, shape)
531531
}
532-
ast::TyParamBound::TraitTyParamBound(ref tref, ast::TraitBoundModifier::Maybe) => {
533-
Some(format!(
534-
"?{}",
535-
tref.rewrite(context, shape.offset_left(1)?)?
536-
))
537-
}
532+
ast::TyParamBound::TraitTyParamBound(ref tref, ast::TraitBoundModifier::Maybe) => Some(
533+
format!("?{}", tref.rewrite(context, shape.offset_left(1)?)?),
534+
),
538535
ast::TyParamBound::RegionTyParamBound(ref l) => l.rewrite(context, shape),
539536
}
540537
}

rustfmt-core/tests/source/macro_rules.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// rustfmt-error_on_line_overflow: false
2+
13
macro_rules! m {
24
// a
35
($expr :expr, $( $func : ident ) * ) => {
@@ -50,12 +52,37 @@ macro m2 {
5052
}
5153
}
5254

53-
54-
// #2438
55+
// #2438, #2476
56+
macro_rules! m {
57+
() => {
58+
fn foo() {
59+
this_line_is_98_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
60+
);
61+
}
62+
}
63+
}
64+
macro_rules! m {
65+
() => {
66+
fn foo() {
67+
this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
68+
);
69+
}
70+
};
71+
}
72+
macro_rules! m {
73+
() => {
74+
fn foo() {
75+
this_line_is_100_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
76+
);
77+
}
78+
};
79+
}
5580
macro_rules! m {
5681
() => {
57-
this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
58-
); // this line is drifting
82+
fn foo() {
83+
this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
84+
);
85+
}
5986
};
6087
}
6188

rustfmt-core/tests/target/configs/indent_style/block_call.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ fn main() {
1313
"elit",
1414
);
1515
// #1501
16-
let hyper = Arc::new(Client::with_connector(HttpsConnector::new(
17-
TlsClient::new(),
18-
)));
16+
let hyper = Arc::new(Client::with_connector(
17+
HttpsConnector::new(TlsClient::new()),
18+
));
1919

2020
// chain
2121
let x = yooooooooooooo

rustfmt-core/tests/target/macro_rules.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// rustfmt-error_on_line_overflow: false
2+
13
macro_rules! m {
24
// a
35
($expr: expr, $($func: ident)*) => {{
@@ -42,11 +44,36 @@ macro m2 {
4244
}
4345
}
4446

45-
// #2438
47+
// #2438, #2476
4648
macro_rules! m {
4749
() => {
48-
this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
49-
); // this line is drifting
50+
fn foo() {
51+
this_line_is_98_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx();
52+
}
53+
};
54+
}
55+
macro_rules! m {
56+
() => {
57+
fn foo() {
58+
this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
59+
);
60+
}
61+
};
62+
}
63+
macro_rules! m {
64+
() => {
65+
fn foo() {
66+
this_line_is_100_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
67+
);
68+
}
69+
};
70+
}
71+
macro_rules! m {
72+
() => {
73+
fn foo() {
74+
this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
75+
);
76+
}
5077
};
5178
}
5279

0 commit comments

Comments
 (0)