Skip to content

Commit 7a0abbf

Browse files
committed
Combining move lifetime and type suggestions.
This commit combines the move lifetime and move type suggestions so that when rustfix applies them they don't conflict with each other.
1 parent 463e623 commit 7a0abbf

File tree

3 files changed

+179
-35
lines changed

3 files changed

+179
-35
lines changed

src/libsyntax/parse/parser.rs

+73-30
Original file line numberDiff line numberDiff line change
@@ -5611,49 +5611,92 @@ impl<'a> Parser<'a> {
56115611
}
56125612
}
56135613

5614-
if !bad_lifetime_pos.is_empty() {
5615-
let mut err = self.struct_span_err(
5614+
self.maybe_report_incorrect_generic_argument_order(
5615+
bad_lifetime_pos, bad_type_pos, lifetime_suggestions, type_suggestions
5616+
);
5617+
5618+
Ok((args, bindings))
5619+
}
5620+
5621+
/// Maybe report an error about incorrect generic argument order - "lifetime parameters
5622+
/// must be declared before type parameters", "type parameters must be declared before
5623+
/// associated type bindings" or both.
5624+
fn maybe_report_incorrect_generic_argument_order(
5625+
&self,
5626+
bad_lifetime_pos: Vec<Span>,
5627+
bad_type_pos: Vec<Span>,
5628+
lifetime_suggestions: Vec<(Span, String)>,
5629+
type_suggestions: Vec<(Span, String)>,
5630+
) {
5631+
let mut err = if !bad_lifetime_pos.is_empty() && !bad_type_pos.is_empty() {
5632+
let mut positions = bad_lifetime_pos.clone();
5633+
positions.extend_from_slice(&bad_type_pos);
5634+
5635+
self.struct_span_err(
5636+
positions,
5637+
"generic arguments must declare lifetimes, types and associated type bindings in \
5638+
that order",
5639+
)
5640+
} else if !bad_lifetime_pos.is_empty() {
5641+
self.struct_span_err(
56165642
bad_lifetime_pos.clone(),
56175643
"lifetime parameters must be declared prior to type parameters"
5618-
);
5644+
)
5645+
} else if !bad_type_pos.is_empty() {
5646+
self.struct_span_err(
5647+
bad_type_pos.clone(),
5648+
"type parameters must be declared prior to associated type bindings"
5649+
)
5650+
} else {
5651+
return;
5652+
};
5653+
5654+
if !bad_lifetime_pos.is_empty() {
56195655
for sp in &bad_lifetime_pos {
56205656
err.span_label(*sp, "must be declared prior to type parameters");
56215657
}
5622-
if !lifetime_suggestions.is_empty() {
5623-
err.multipart_suggestion_with_applicability(
5624-
&format!(
5625-
"move the lifetime parameter{} prior to the first type parameter",
5626-
if bad_lifetime_pos.len() > 1 { "s" } else { "" },
5627-
),
5628-
lifetime_suggestions,
5629-
Applicability::MachineApplicable,
5630-
);
5631-
}
5632-
err.emit();
56335658
}
56345659

56355660
if !bad_type_pos.is_empty() {
5636-
let mut err = self.struct_span_err(
5637-
bad_type_pos.clone(),
5638-
"type parameters must be declared prior to associated type bindings"
5639-
);
56405661
for sp in &bad_type_pos {
56415662
err.span_label(*sp, "must be declared prior to associated type bindings");
56425663
}
5643-
if !type_suggestions.is_empty() {
5644-
err.multipart_suggestion_with_applicability(
5645-
&format!(
5646-
"move the type parameter{} prior to the first associated type binding",
5647-
if bad_type_pos.len() > 1 { "s" } else { "" },
5648-
),
5649-
type_suggestions,
5650-
Applicability::MachineApplicable,
5651-
);
5652-
}
5653-
err.emit();
56545664
}
56555665

5656-
Ok((args, bindings))
5666+
if !lifetime_suggestions.is_empty() && !type_suggestions.is_empty() {
5667+
let mut suggestions = lifetime_suggestions;
5668+
suggestions.extend_from_slice(&type_suggestions);
5669+
5670+
let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1;
5671+
err.multipart_suggestion_with_applicability(
5672+
&format!(
5673+
"move the parameter{}",
5674+
if plural { "s" } else { "" },
5675+
),
5676+
suggestions,
5677+
Applicability::MachineApplicable,
5678+
);
5679+
} else if !lifetime_suggestions.is_empty() {
5680+
err.multipart_suggestion_with_applicability(
5681+
&format!(
5682+
"move the lifetime parameter{} prior to the first type parameter",
5683+
if bad_lifetime_pos.len() > 1 { "s" } else { "" },
5684+
),
5685+
lifetime_suggestions,
5686+
Applicability::MachineApplicable,
5687+
);
5688+
} else if !type_suggestions.is_empty() {
5689+
err.multipart_suggestion_with_applicability(
5690+
&format!(
5691+
"move the type parameter{} prior to the first associated type binding",
5692+
if bad_type_pos.len() > 1 { "s" } else { "" },
5693+
),
5694+
type_suggestions,
5695+
Applicability::MachineApplicable,
5696+
);
5697+
}
5698+
5699+
err.emit();
56575700
}
56585701

56595702
/// Parses an optional `where` clause and places it in `generics`.

src/test/ui/suggestions/suggest-move-types.rs

+43
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-tidy-linelength
2+
13
#![allow(warnings)]
24

35
// This test verifies that the suggestion to move types before associated type bindings
@@ -7,36 +9,77 @@ trait One<T> {
79
type A;
810
}
911

12+
trait OneWithLifetime<'a, T> {
13+
type A;
14+
}
15+
1016
trait Three<T, U, V> {
1117
type A;
1218
type B;
1319
type C;
1420
}
1521

22+
trait ThreeWithLifetime<'a, 'b, 'c, T, U, V> {
23+
type A;
24+
type B;
25+
type C;
26+
}
27+
1628
struct A<T, M: One<A=(), T>> { //~ ERROR type parameters must be declared
1729
m: M,
1830
t: T,
1931
}
2032

33+
34+
struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
35+
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
36+
m: M,
37+
t: &'a T,
38+
}
39+
2140
struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type parameters must be declared
2241
m: M,
2342
t: T,
2443
u: U,
2544
v: V,
2645
}
2746

47+
struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
48+
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
49+
m: M,
50+
t: &'a T,
51+
u: &'b U,
52+
v: &'c V,
53+
}
54+
2855
struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type parameters must be declared
2956
m: M,
3057
t: T,
3158
u: U,
3259
v: V,
3360
}
3461

62+
struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
63+
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
64+
m: M,
65+
t: &'a T,
66+
u: &'b U,
67+
v: &'c V,
68+
}
69+
3570
struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type parameters must be declared
3671
m: M,
3772
t: T,
3873
u: U,
3974
v: V,
4075
}
4176

77+
struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
78+
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
79+
m: M,
80+
t: &'a T,
81+
u: &'b U,
82+
v: &'c V,
83+
}
84+
4285
fn main() {}

src/test/ui/suggestions/suggest-move-types.stderr

+63-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: type parameters must be declared prior to associated type bindings
2-
--> $DIR/suggest-move-types.rs:16:26
2+
--> $DIR/suggest-move-types.rs:28:26
33
|
44
LL | struct A<T, M: One<A=(), T>> { //~ ERROR type parameters must be declared
55
| ^ must be declared prior to associated type bindings
@@ -8,8 +8,20 @@ help: move the type parameter prior to the first associated type binding
88
LL | struct A<T, M: One<T, A=()>> { //~ ERROR type parameters must be declared
99
| ^^ --
1010

11+
error: generic arguments must declare lifetimes, types and associated type bindings in that order
12+
--> $DIR/suggest-move-types.rs:34:46
13+
|
14+
LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
15+
| ^ ^^ must be declared prior to type parameters
16+
| |
17+
| must be declared prior to associated type bindings
18+
help: move the parameters
19+
|
20+
LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A=()>> {
21+
| ^^^ ^^ --
22+
1123
error: type parameters must be declared prior to associated type bindings
12-
--> $DIR/suggest-move-types.rs:21:46
24+
--> $DIR/suggest-move-types.rs:40:46
1325
|
1426
LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type parameters must be declared
1527
| ^ ^ ^ must be declared prior to associated type bindings
@@ -21,8 +33,24 @@ help: move the type parameters prior to the first associated type binding
2133
LL | struct B<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
2234
| ^^ ^^ ^^ --
2335

36+
error: generic arguments must declare lifetimes, types and associated type bindings in that order
37+
--> $DIR/suggest-move-types.rs:47:80
38+
|
39+
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
40+
| ^ ^ ^ ^^ ^^ ^^ must be declared prior to type parameters
41+
| | | | | |
42+
| | | | | must be declared prior to type parameters
43+
| | | | must be declared prior to type parameters
44+
| | | must be declared prior to associated type bindings
45+
| | must be declared prior to associated type bindings
46+
| must be declared prior to associated type bindings
47+
help: move the parameters
48+
|
49+
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
50+
| ^^^ ^^^ ^^^ ^^ ^^ ^^ --
51+
2452
error: type parameters must be declared prior to associated type bindings
25-
--> $DIR/suggest-move-types.rs:28:49
53+
--> $DIR/suggest-move-types.rs:55:49
2654
|
2755
LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type parameters must be declared
2856
| ^ ^ must be declared prior to associated type bindings
@@ -33,8 +61,23 @@ help: move the type parameters prior to the first associated type binding
3361
LL | struct C<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
3462
| ^^ ^^ --
3563

64+
error: generic arguments must declare lifetimes, types and associated type bindings in that order
65+
--> $DIR/suggest-move-types.rs:62:56
66+
|
67+
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
68+
| ^^ ^ ^^ ^ ^^ must be declared prior to type parameters
69+
| | | | |
70+
| | | | must be declared prior to associated type bindings
71+
| | | must be declared prior to type parameters
72+
| | must be declared prior to associated type bindings
73+
| must be declared prior to type parameters
74+
help: move the parameters
75+
|
76+
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
77+
| ^^^ ^^^ ^^^ -- ^^ ^^ --
78+
3679
error: type parameters must be declared prior to associated type bindings
37-
--> $DIR/suggest-move-types.rs:35:43
80+
--> $DIR/suggest-move-types.rs:70:43
3881
|
3982
LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type parameters must be declared
4083
| ^ ^ must be declared prior to associated type bindings
@@ -45,5 +88,20 @@ help: move the type parameters prior to the first associated type binding
4588
LL | struct D<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
4689
| ^^ ^^ -- --
4790

48-
error: aborting due to 4 previous errors
91+
error: generic arguments must declare lifetimes, types and associated type bindings in that order
92+
--> $DIR/suggest-move-types.rs:77:56
93+
|
94+
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
95+
| ^^ ^ ^^ ^ ^^ must be declared prior to type parameters
96+
| | | | |
97+
| | | | must be declared prior to associated type bindings
98+
| | | must be declared prior to type parameters
99+
| | must be declared prior to associated type bindings
100+
| must be declared prior to type parameters
101+
help: move the parameters
102+
|
103+
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
104+
| ^^^ ^^^ ^^^ -- ^^ ^^ -- --
105+
106+
error: aborting due to 8 previous errors
49107

0 commit comments

Comments
 (0)