Skip to content

Commit 8ff2836

Browse files
authored
Merge pull request #2861 from topecongiro/issue-2859
Put lifetimes after trait when they gets orphaned
2 parents e3fea15 + 6cecdd6 commit 8ff2836

File tree

5 files changed

+126
-14
lines changed

5 files changed

+126
-14
lines changed

src/items.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1752,11 +1752,10 @@ pub fn rewrite_associated_impl_type(
17521752
ident: ast::Ident,
17531753
defaultness: ast::Defaultness,
17541754
ty_opt: Option<&ptr::P<ast::Ty>>,
1755-
generic_bounds_opt: Option<&ast::GenericBounds>,
17561755
context: &RewriteContext,
17571756
indent: Indent,
17581757
) -> Option<String> {
1759-
let result = rewrite_associated_type(ident, ty_opt, generic_bounds_opt, context, indent)?;
1758+
let result = rewrite_associated_type(ident, ty_opt, None, context, indent)?;
17601759

17611760
match defaultness {
17621761
ast::Defaultness::Default => Some(format!("default {}", result)),

src/types.rs

+42-11
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ use rewrite::{Rewrite, RewriteContext};
2727
use shape::Shape;
2828
use spanned::Spanned;
2929
use utils::{
30-
colon_spaces, extra_offset, first_line_width, format_abi, format_mutability, last_line_width,
31-
mk_sp, rewrite_ident,
30+
colon_spaces, extra_offset, first_line_width, format_abi, format_mutability,
31+
last_line_extendable, last_line_width, mk_sp, rewrite_ident,
3232
};
3333

3434
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -733,15 +733,28 @@ fn rewrite_bare_fn(
733733
Some(result)
734734
}
735735

736-
fn join_bounds<T>(
736+
fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool {
737+
let is_trait = |b: &ast::GenericBound| match b {
738+
ast::GenericBound::Outlives(..) => false,
739+
ast::GenericBound::Trait(..) => true,
740+
};
741+
let is_lifetime = |b: &ast::GenericBound| !is_trait(b);
742+
let last_trait_index = generic_bounds.iter().rposition(is_trait);
743+
let first_lifetime_index = generic_bounds.iter().position(is_lifetime);
744+
match (last_trait_index, first_lifetime_index) {
745+
(Some(last_trait_index), Some(first_lifetime_index)) => {
746+
last_trait_index < first_lifetime_index
747+
}
748+
_ => true,
749+
}
750+
}
751+
752+
fn join_bounds(
737753
context: &RewriteContext,
738754
shape: Shape,
739-
items: &[T],
755+
items: &[ast::GenericBound],
740756
need_indent: bool,
741-
) -> Option<String>
742-
where
743-
T: Rewrite,
744-
{
757+
) -> Option<String> {
745758
// Try to join types in a single line
746759
let joiner = match context.config.type_punctuation_density() {
747760
TypeDensity::Compressed => "+",
@@ -752,7 +765,7 @@ where
752765
.map(|item| item.rewrite(context, shape))
753766
.collect::<Option<Vec<_>>>()?;
754767
let result = type_strs.join(joiner);
755-
if items.len() == 1 || (!result.contains('\n') && result.len() <= shape.width) {
768+
if items.len() <= 1 || (!result.contains('\n') && result.len() <= shape.width) {
756769
return Some(result);
757770
}
758771

@@ -769,8 +782,26 @@ where
769782
(type_strs, shape.indent)
770783
};
771784

772-
let joiner = format!("{}+ ", offset.to_string_with_newline(context.config));
773-
Some(type_strs.join(&joiner))
785+
let is_bound_extendable = |s: &str, b: &ast::GenericBound| match b {
786+
ast::GenericBound::Outlives(..) => true,
787+
ast::GenericBound::Trait(..) => last_line_extendable(s),
788+
};
789+
let mut result = String::with_capacity(128);
790+
result.push_str(&type_strs[0]);
791+
let mut can_be_put_on_the_same_line = is_bound_extendable(&result, &items[0]);
792+
let generic_bounds_in_order = is_generic_bounds_in_order(items);
793+
for (bound, bound_str) in items[1..].iter().zip(type_strs[1..].iter()) {
794+
if generic_bounds_in_order && can_be_put_on_the_same_line {
795+
result.push_str(joiner);
796+
} else {
797+
result.push_str(&offset.to_string_with_newline(context.config));
798+
result.push_str("+ ");
799+
}
800+
result.push_str(bound_str);
801+
can_be_put_on_the_same_line = is_bound_extendable(bound_str, bound);
802+
}
803+
804+
Some(result)
774805
}
775806

776807
pub fn can_be_overflowed_type(context: &RewriteContext, ty: &ast::Ty, len: usize) -> bool {

src/visitor.rs

-1
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,6 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
515515
ii.ident,
516516
ii.defaultness,
517517
Some(ty),
518-
None,
519518
&self.get_context(),
520519
self.block_indent,
521520
);

tests/source/type.rs

+44
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,47 @@ impl CombineTypes {
3838
self.query_callbacks()(&query_id)
3939
}
4040
}
41+
42+
// #2859
43+
pub fn do_something<'a, T: Trait1 + Trait2 + 'a>(&fooo: u32) -> impl Future<
44+
Item = (
45+
impl Future<Item = (
46+
), Error = SomeError> + 'a,
47+
impl Future<Item = (), Error = SomeError> + 'a,
48+
impl Future<Item = (), Error = SomeError > + 'a,
49+
),
50+
Error = SomeError,
51+
>
52+
+
53+
'a {
54+
}
55+
56+
pub fn do_something<'a, T: Trait1 + Trait2 + 'a>( &fooo: u32,
57+
) -> impl Future<
58+
Item = (
59+
impl Future<Item = (), Error = SomeError> + 'a,
60+
impl Future<Item = (), Error = SomeError> + 'a,
61+
impl Future<Item = (), Error = SomeError> + 'a,
62+
),
63+
Error = SomeError,
64+
>
65+
+ Future<
66+
Item = (
67+
impl Future<Item = (), Error = SomeError> + 'a,
68+
impl Future<Item = (), Error = SomeError> + 'a,
69+
impl Future<Item = (), Error = SomeError> + 'a,
70+
),
71+
Error = SomeError,
72+
>
73+
+ Future<
74+
Item = (
75+
impl Future<Item = (), Error = SomeError> + 'a,
76+
impl Future<Item = (), Error = SomeError> + 'a,
77+
impl Future<Item = (), Error = SomeError> + 'a,
78+
),
79+
Error = SomeError,
80+
>
81+
+
82+
'a + 'b +
83+
'c {
84+
}

tests/target/type.rs

+39
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,42 @@ impl CombineTypes {
4242
self.query_callbacks()(&query_id)
4343
}
4444
}
45+
46+
// #2859
47+
pub fn do_something<'a, T: Trait1 + Trait2 + 'a>(
48+
&fooo: u32,
49+
) -> impl Future<
50+
Item = (
51+
impl Future<Item = (), Error = SomeError> + 'a,
52+
impl Future<Item = (), Error = SomeError> + 'a,
53+
impl Future<Item = (), Error = SomeError> + 'a,
54+
),
55+
Error = SomeError,
56+
> + 'a {
57+
}
58+
59+
pub fn do_something<'a, T: Trait1 + Trait2 + 'a>(
60+
&fooo: u32,
61+
) -> impl Future<
62+
Item = (
63+
impl Future<Item = (), Error = SomeError> + 'a,
64+
impl Future<Item = (), Error = SomeError> + 'a,
65+
impl Future<Item = (), Error = SomeError> + 'a,
66+
),
67+
Error = SomeError,
68+
> + Future<
69+
Item = (
70+
impl Future<Item = (), Error = SomeError> + 'a,
71+
impl Future<Item = (), Error = SomeError> + 'a,
72+
impl Future<Item = (), Error = SomeError> + 'a,
73+
),
74+
Error = SomeError,
75+
> + Future<
76+
Item = (
77+
impl Future<Item = (), Error = SomeError> + 'a,
78+
impl Future<Item = (), Error = SomeError> + 'a,
79+
impl Future<Item = (), Error = SomeError> + 'a,
80+
),
81+
Error = SomeError,
82+
> + 'a + 'b + 'c {
83+
}

0 commit comments

Comments
 (0)