Skip to content

Commit 1643d72

Browse files
authored
Use correct indent when formatting complex fn type (rust-lang#3731)
1 parent dfd2766 commit 1643d72

File tree

6 files changed

+139
-25
lines changed

6 files changed

+139
-25
lines changed

src/items.rs

+47-19
Original file line numberDiff line numberDiff line change
@@ -1822,9 +1822,17 @@ impl Rewrite for ast::FunctionRetTy {
18221822
match *self {
18231823
ast::FunctionRetTy::Default(_) => Some(String::new()),
18241824
ast::FunctionRetTy::Ty(ref ty) => {
1825-
let inner_width = shape.width.checked_sub(3)?;
1826-
ty.rewrite(context, Shape::legacy(inner_width, shape.indent + 3))
1827-
.map(|r| format!("-> {}", r))
1825+
if context.config.version() == Version::One
1826+
|| context.config.indent_style() == IndentStyle::Visual
1827+
{
1828+
let inner_width = shape.width.checked_sub(3)?;
1829+
return ty
1830+
.rewrite(context, Shape::legacy(inner_width, shape.indent + 3))
1831+
.map(|r| format!("-> {}", r));
1832+
}
1833+
1834+
ty.rewrite(context, shape.offset_left(3)?)
1835+
.map(|s| format!("-> {}", s))
18281836
}
18291837
}
18301838
}
@@ -2147,20 +2155,39 @@ fn rewrite_fn_base(
21472155
sig_length > context.config.max_width()
21482156
}
21492157
};
2150-
let ret_indent = if ret_should_indent {
2151-
let indent = if arg_str.is_empty() {
2152-
// Aligning with non-existent args looks silly.
2153-
force_new_line_for_brace = true;
2154-
indent + 4
2158+
let ret_shape = if ret_should_indent {
2159+
if context.config.version() == Version::One
2160+
|| context.config.indent_style() == IndentStyle::Visual
2161+
{
2162+
let indent = if arg_str.is_empty() {
2163+
// Aligning with non-existent args looks silly.
2164+
force_new_line_for_brace = true;
2165+
indent + 4
2166+
} else {
2167+
// FIXME: we might want to check that using the arg indent
2168+
// doesn't blow our budget, and if it does, then fallback to
2169+
// the where-clause indent.
2170+
arg_indent
2171+
};
2172+
2173+
result.push_str(&indent.to_string_with_newline(context.config));
2174+
Shape::indented(indent, context.config)
21552175
} else {
2156-
// FIXME: we might want to check that using the arg indent
2157-
// doesn't blow our budget, and if it does, then fallback to
2158-
// the where-clause indent.
2159-
arg_indent
2160-
};
2176+
let mut ret_shape = Shape::indented(indent, context.config);
2177+
if arg_str.is_empty() {
2178+
// Aligning with non-existent args looks silly.
2179+
force_new_line_for_brace = true;
2180+
ret_shape = if context.use_block_indent() {
2181+
ret_shape.offset_left(4).unwrap_or(ret_shape)
2182+
} else {
2183+
ret_shape.indent = ret_shape.indent + 4;
2184+
ret_shape
2185+
};
2186+
}
21612187

2162-
result.push_str(&indent.to_string_with_newline(context.config));
2163-
indent
2188+
result.push_str(&ret_shape.indent.to_string_with_newline(context.config));
2189+
ret_shape
2190+
}
21642191
} else {
21652192
if context.config.version() == Version::Two {
21662193
if !arg_str.is_empty() || !no_args_and_over_max_width {
@@ -2170,15 +2197,16 @@ fn rewrite_fn_base(
21702197
result.push(' ');
21712198
}
21722199

2173-
Indent::new(indent.block_indent, last_line_width(&result))
2200+
let ret_shape = Shape::indented(indent, context.config);
2201+
ret_shape
2202+
.offset_left(last_line_width(&result))
2203+
.unwrap_or(ret_shape)
21742204
};
21752205

21762206
if multi_line_ret_str || ret_should_indent {
21772207
// Now that we know the proper indent and width, we need to
21782208
// re-layout the return type.
2179-
let ret_str = fd
2180-
.output
2181-
.rewrite(context, Shape::indented(ret_indent, context.config))?;
2209+
let ret_str = fd.output.rewrite(context, ret_shape)?;
21822210
result.push_str(&ret_str);
21832211
} else {
21842212
result.push_str(&ret_str);

src/types.rs

+42-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use syntax::source_map::{self, BytePos, Span};
66
use syntax::symbol::kw;
77

88
use crate::config::lists::*;
9-
use crate::config::{IndentStyle, TypeDensity};
9+
use crate::config::{IndentStyle, TypeDensity, Version};
1010
use crate::expr::{format_expr, rewrite_assign_rhs, rewrite_tuple, rewrite_unary_prefix, ExprType};
1111
use crate::lists::{
1212
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
@@ -678,9 +678,35 @@ impl Rewrite for ast::Ty {
678678
// FIXME: we drop any comments here, even though it's a silly place to put
679679
// comments.
680680
ast::TyKind::Paren(ref ty) => {
681-
let budget = shape.width.checked_sub(2)?;
682-
ty.rewrite(context, Shape::legacy(budget, shape.indent + 1))
683-
.map(|ty_str| format!("({})", ty_str))
681+
if context.config.version() == Version::One
682+
|| context.config.indent_style() == IndentStyle::Visual
683+
{
684+
let budget = shape.width.checked_sub(2)?;
685+
return ty
686+
.rewrite(context, Shape::legacy(budget, shape.indent + 1))
687+
.map(|ty_str| format!("({})", ty_str));
688+
}
689+
690+
// 2 = ()
691+
if let Some(sh) = shape.sub_width(2) {
692+
if let Some(ref s) = ty.rewrite(context, sh) {
693+
if !s.contains('\n') {
694+
return Some(format!("({})", s));
695+
}
696+
}
697+
}
698+
699+
let indent_str = shape.indent.to_string_with_newline(context.config);
700+
let shape = shape
701+
.block_indent(context.config.tab_spaces())
702+
.with_max_width(context.config);
703+
let rw = ty.rewrite(context, shape)?;
704+
Some(format!(
705+
"({}{}{})",
706+
shape.to_string_with_newline(context.config),
707+
rw,
708+
indent_str
709+
))
684710
}
685711
ast::TyKind::Slice(ref ty) => {
686712
let budget = shape.width.checked_sub(4)?;
@@ -716,7 +742,15 @@ impl Rewrite for ast::Ty {
716742
ast::TyKind::ImplicitSelf => Some(String::from("")),
717743
ast::TyKind::ImplTrait(_, ref it) => {
718744
// Empty trait is not a parser error.
719-
it.rewrite(context, shape).map(|it_str| {
745+
if it.is_empty() {
746+
return Some("impl".to_owned());
747+
}
748+
let rw = if context.config.version() == Version::One {
749+
it.rewrite(context, shape)
750+
} else {
751+
join_bounds(context, shape, it, false)
752+
};
753+
rw.map(|it_str| {
720754
let space = if it_str.is_empty() { "" } else { " " };
721755
format!("impl{}{}", space, it_str)
722756
})
@@ -818,7 +852,9 @@ fn join_bounds(
818852
// We need to use multiple lines.
819853
let (type_strs, offset) = if need_indent {
820854
// Rewrite with additional indentation.
821-
let nested_shape = shape.block_indent(context.config.tab_spaces());
855+
let nested_shape = shape
856+
.block_indent(context.config.tab_spaces())
857+
.with_max_width(context.config);
822858
let type_strs = items
823859
.iter()
824860
.map(|item| item.rewrite(context, nested_shape))

tests/source/issue-3701/one.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-version: One
2+
3+
fn build_sorted_static_get_entry_names(
4+
mut entries: Vec<(u8, &'static str)>,
5+
) -> (impl Fn(
6+
AlphabeticalTraversal,
7+
Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
8+
) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
9+
+ Send
10+
+ Sync
11+
+ 'static) {
12+
}

tests/source/issue-3701/two.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-version: Two
2+
3+
fn build_sorted_static_get_entry_names(
4+
mut entries: Vec<(u8, &'static str)>,
5+
) -> (impl Fn(
6+
AlphabeticalTraversal,
7+
Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
8+
) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
9+
+ Send
10+
+ Sync
11+
+ 'static) {
12+
}

tests/target/issue-3701/one.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-version: One
2+
3+
fn build_sorted_static_get_entry_names(
4+
mut entries: Vec<(u8, &'static str)>,
5+
) -> (impl Fn(
6+
AlphabeticalTraversal,
7+
Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
8+
) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
9+
+ Send
10+
+ Sync
11+
+ 'static) {
12+
}

tests/target/issue-3701/two.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// rustfmt-version: Two
2+
3+
fn build_sorted_static_get_entry_names(
4+
mut entries: Vec<(u8, &'static str)>,
5+
) -> (
6+
impl Fn(
7+
AlphabeticalTraversal,
8+
Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
9+
) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
10+
+ Send
11+
+ Sync
12+
+ 'static
13+
) {
14+
}

0 commit comments

Comments
 (0)