diff --git a/src/items.rs b/src/items.rs index 73b752dfe78..096ce2fa298 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1821,9 +1821,17 @@ impl Rewrite for ast::FunctionRetTy { match *self { ast::FunctionRetTy::Default(_) => Some(String::new()), ast::FunctionRetTy::Ty(ref ty) => { - let inner_width = shape.width.checked_sub(3)?; - ty.rewrite(context, Shape::legacy(inner_width, shape.indent + 3)) - .map(|r| format!("-> {}", r)) + if context.config.version() == Version::One + || context.config.indent_style() == IndentStyle::Visual + { + let inner_width = shape.width.checked_sub(3)?; + return ty + .rewrite(context, Shape::legacy(inner_width, shape.indent + 3)) + .map(|r| format!("-> {}", r)); + } + + ty.rewrite(context, shape.offset_left(3)?) + .map(|s| format!("-> {}", s)) } } } @@ -2146,20 +2154,39 @@ fn rewrite_fn_base( sig_length > context.config.max_width() } }; - let ret_indent = if ret_should_indent { - let indent = if arg_str.is_empty() { - // Aligning with non-existent args looks silly. - force_new_line_for_brace = true; - indent + 4 + let ret_shape = if ret_should_indent { + if context.config.version() == Version::One + || context.config.indent_style() == IndentStyle::Visual + { + let indent = if arg_str.is_empty() { + // Aligning with non-existent args looks silly. + force_new_line_for_brace = true; + indent + 4 + } else { + // FIXME: we might want to check that using the arg indent + // doesn't blow our budget, and if it does, then fallback to + // the where-clause indent. + arg_indent + }; + + result.push_str(&indent.to_string_with_newline(context.config)); + Shape::indented(indent, context.config) } else { - // FIXME: we might want to check that using the arg indent - // doesn't blow our budget, and if it does, then fallback to - // the where-clause indent. - arg_indent - }; + let mut ret_shape = Shape::indented(indent, context.config); + if arg_str.is_empty() { + // Aligning with non-existent args looks silly. + force_new_line_for_brace = true; + ret_shape = if context.use_block_indent() { + ret_shape.offset_left(4).unwrap_or(ret_shape) + } else { + ret_shape.indent = ret_shape.indent + 4; + ret_shape + }; + } - result.push_str(&indent.to_string_with_newline(context.config)); - indent + result.push_str(&ret_shape.indent.to_string_with_newline(context.config)); + ret_shape + } } else { if context.config.version() == Version::Two { if !arg_str.is_empty() || !no_args_and_over_max_width { @@ -2169,15 +2196,16 @@ fn rewrite_fn_base( result.push(' '); } - Indent::new(indent.block_indent, last_line_width(&result)) + let ret_shape = Shape::indented(indent, context.config); + ret_shape + .offset_left(last_line_width(&result)) + .unwrap_or(ret_shape) }; if multi_line_ret_str || ret_should_indent { // Now that we know the proper indent and width, we need to // re-layout the return type. - let ret_str = fd - .output - .rewrite(context, Shape::indented(ret_indent, context.config))?; + let ret_str = fd.output.rewrite(context, ret_shape)?; result.push_str(&ret_str); } else { result.push_str(&ret_str); diff --git a/src/types.rs b/src/types.rs index d09e8c01e38..012cdba3192 100644 --- a/src/types.rs +++ b/src/types.rs @@ -6,7 +6,7 @@ use syntax::source_map::{self, BytePos, Span}; use syntax::symbol::kw; use crate::config::lists::*; -use crate::config::{IndentStyle, TypeDensity}; +use crate::config::{IndentStyle, TypeDensity, Version}; use crate::expr::{format_expr, rewrite_assign_rhs, rewrite_tuple, rewrite_unary_prefix, ExprType}; use crate::lists::{ definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator, @@ -678,9 +678,35 @@ impl Rewrite for ast::Ty { // FIXME: we drop any comments here, even though it's a silly place to put // comments. ast::TyKind::Paren(ref ty) => { - let budget = shape.width.checked_sub(2)?; - ty.rewrite(context, Shape::legacy(budget, shape.indent + 1)) - .map(|ty_str| format!("({})", ty_str)) + if context.config.version() == Version::One + || context.config.indent_style() == IndentStyle::Visual + { + let budget = shape.width.checked_sub(2)?; + return ty + .rewrite(context, Shape::legacy(budget, shape.indent + 1)) + .map(|ty_str| format!("({})", ty_str)); + } + + // 2 = () + if let Some(sh) = shape.sub_width(2) { + if let Some(ref s) = ty.rewrite(context, sh) { + if !s.contains('\n') { + return Some(format!("({})", s)); + } + } + } + + let indent_str = shape.indent.to_string_with_newline(context.config); + let shape = shape + .block_indent(context.config.tab_spaces()) + .with_max_width(context.config); + let rw = ty.rewrite(context, shape)?; + Some(format!( + "({}{}{})", + shape.to_string_with_newline(context.config), + rw, + indent_str + )) } ast::TyKind::Slice(ref ty) => { let budget = shape.width.checked_sub(4)?; @@ -716,7 +742,15 @@ impl Rewrite for ast::Ty { ast::TyKind::ImplicitSelf => Some(String::from("")), ast::TyKind::ImplTrait(_, ref it) => { // Empty trait is not a parser error. - it.rewrite(context, shape).map(|it_str| { + if it.is_empty() { + return Some("impl".to_owned()); + } + let rw = if context.config.version() == Version::One { + it.rewrite(context, shape) + } else { + join_bounds(context, shape, it, false) + }; + rw.map(|it_str| { let space = if it_str.is_empty() { "" } else { " " }; format!("impl{}{}", space, it_str) }) @@ -818,7 +852,9 @@ fn join_bounds( // We need to use multiple lines. let (type_strs, offset) = if need_indent { // Rewrite with additional indentation. - let nested_shape = shape.block_indent(context.config.tab_spaces()); + let nested_shape = shape + .block_indent(context.config.tab_spaces()) + .with_max_width(context.config); let type_strs = items .iter() .map(|item| item.rewrite(context, nested_shape)) diff --git a/tests/source/issue-3701/one.rs b/tests/source/issue-3701/one.rs new file mode 100644 index 00000000000..a7f0bd3aa17 --- /dev/null +++ b/tests/source/issue-3701/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> (impl Fn( + AlphabeticalTraversal, + Box>, +) -> BoxFuture<'static, Result, Status>> + + Send + + Sync + + 'static) { +} diff --git a/tests/source/issue-3701/two.rs b/tests/source/issue-3701/two.rs new file mode 100644 index 00000000000..8e15c58b8b2 --- /dev/null +++ b/tests/source/issue-3701/two.rs @@ -0,0 +1,12 @@ +// rustfmt-version: Two + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> (impl Fn( + AlphabeticalTraversal, + Box>, +) -> BoxFuture<'static, Result, Status>> + + Send + + Sync + + 'static) { +} diff --git a/tests/target/issue-3701/one.rs b/tests/target/issue-3701/one.rs new file mode 100644 index 00000000000..9d1ef9eed9a --- /dev/null +++ b/tests/target/issue-3701/one.rs @@ -0,0 +1,12 @@ +// rustfmt-version: One + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> (impl Fn( + AlphabeticalTraversal, + Box>, +) -> BoxFuture<'static, Result, Status>> + + Send + + Sync + + 'static) { +} diff --git a/tests/target/issue-3701/two.rs b/tests/target/issue-3701/two.rs new file mode 100644 index 00000000000..62ffc9d823d --- /dev/null +++ b/tests/target/issue-3701/two.rs @@ -0,0 +1,14 @@ +// rustfmt-version: Two + +fn build_sorted_static_get_entry_names( + mut entries: Vec<(u8, &'static str)>, +) -> ( + impl Fn( + AlphabeticalTraversal, + Box>, + ) -> BoxFuture<'static, Result, Status>> + + Send + + Sync + + 'static +) { +}