From 6b33043e060460f799f60324e05c8b87b721943c Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 13 Oct 2018 00:40:34 +0900 Subject: [PATCH 1/2] Add a test for #3060 --- tests/source/type.rs | 9 +++++++++ tests/target/type.rs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/source/type.rs b/tests/source/type.rs index 8d941fc0ab7..2df68490d5d 100644 --- a/tests/source/type.rs +++ b/tests/source/type.rs @@ -82,3 +82,12 @@ impl Future + 'a, 'a + 'b + 'c { } + +// #3060 +macro_rules! foo { + ($foo_api: ty) => { + type Target = ( $foo_api ) + 'static; + } +} + +type Target = ( FooAPI ) + 'static; diff --git a/tests/target/type.rs b/tests/target/type.rs index b3a56d9ed2d..7fb6e0fdf25 100644 --- a/tests/target/type.rs +++ b/tests/target/type.rs @@ -81,3 +81,12 @@ pub fn do_something<'a, T: Trait1 + Trait2 + 'a>( Error = SomeError, > + 'a + 'b + 'c { } + +// #3060 +macro_rules! foo { + ($foo_api: ty) => { + type Target = ($foo_api) + 'static; + }; +} + +type Target = (FooAPI) + 'static; From 0ac68c9477739532166c1f9a62d317fdf4450ae6 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 13 Oct 2018 00:41:17 +0900 Subject: [PATCH 2/2] Do not add parens around lifetimes Parens should be added only around trait objects. --- src/types.rs | 54 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/src/types.rs b/src/types.rs index e7282c13317..d5010314b57 100644 --- a/src/types.rs +++ b/src/types.rs @@ -473,7 +473,7 @@ fn rewrite_bounded_lifetime( "{}{}{}", result, colon, - join_bounds(context, shape.sub_width(overhead)?, bounds, true)? + join_bounds(context, shape.sub_width(overhead)?, bounds, true, false)? ); Some(result) } @@ -515,13 +515,7 @@ impl Rewrite for ast::GenericBounds { } else { shape }; - join_bounds(context, bounds_shape, self, true).map(|s| { - if has_paren { - format!("({})", s) - } else { - s - } - }) + join_bounds(context, bounds_shape, self, true, has_paren) } } @@ -757,7 +751,10 @@ fn join_bounds( shape: Shape, items: &[ast::GenericBound], need_indent: bool, + has_paren: bool, ) -> Option { + debug_assert!(!items.is_empty()); + // Try to join types in a single line let joiner = match context.config.type_punctuation_density() { TypeDensity::Compressed => "+", @@ -765,9 +762,36 @@ fn join_bounds( }; let type_strs = items .iter() - .map(|item| item.rewrite(context, shape)) + .map(|item| { + item.rewrite( + context, + if has_paren { + shape.sub_width(1)?.offset_left(1)? + } else { + shape + }, + ) + }) .collect::>>()?; - let result = type_strs.join(joiner); + let mut result = String::with_capacity(128); + let mut closing_paren = has_paren; + if has_paren { + result.push('('); + } + result.push_str(&type_strs[0]); + if has_paren && type_strs.len() == 1 { + result.push(')'); + } + for (i, type_str) in type_strs[1..].iter().enumerate() { + if closing_paren { + if let ast::GenericBound::Outlives(..) = items[i + 1] { + result.push(')'); + closing_paren = false; + } + } + result.push_str(joiner); + result.push_str(type_str); + } if items.len() <= 1 || (!result.contains('\n') && result.len() <= shape.width) { return Some(result); } @@ -790,10 +814,20 @@ fn join_bounds( ast::GenericBound::Trait(..) => last_line_extendable(s), }; let mut result = String::with_capacity(128); + let mut closing_paren = has_paren; + if has_paren { + result.push('('); + } result.push_str(&type_strs[0]); let mut can_be_put_on_the_same_line = is_bound_extendable(&result, &items[0]); let generic_bounds_in_order = is_generic_bounds_in_order(items); for (bound, bound_str) in items[1..].iter().zip(type_strs[1..].iter()) { + if closing_paren { + if let ast::GenericBound::Outlives(..) = bound { + closing_paren = false; + result.push(')'); + } + } if generic_bounds_in_order && can_be_put_on_the_same_line { result.push_str(joiner); } else {