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.
This commit is contained in:
parent
463e623ca9
commit
7a0abbff8b
3 changed files with 179 additions and 35 deletions
|
@ -5611,49 +5611,92 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
if !bad_lifetime_pos.is_empty() {
|
||||
let mut err = self.struct_span_err(
|
||||
self.maybe_report_incorrect_generic_argument_order(
|
||||
bad_lifetime_pos, bad_type_pos, lifetime_suggestions, type_suggestions
|
||||
);
|
||||
|
||||
Ok((args, bindings))
|
||||
}
|
||||
|
||||
/// Maybe report an error about incorrect generic argument order - "lifetime parameters
|
||||
/// must be declared before type parameters", "type parameters must be declared before
|
||||
/// associated type bindings" or both.
|
||||
fn maybe_report_incorrect_generic_argument_order(
|
||||
&self,
|
||||
bad_lifetime_pos: Vec<Span>,
|
||||
bad_type_pos: Vec<Span>,
|
||||
lifetime_suggestions: Vec<(Span, String)>,
|
||||
type_suggestions: Vec<(Span, String)>,
|
||||
) {
|
||||
let mut err = if !bad_lifetime_pos.is_empty() && !bad_type_pos.is_empty() {
|
||||
let mut positions = bad_lifetime_pos.clone();
|
||||
positions.extend_from_slice(&bad_type_pos);
|
||||
|
||||
self.struct_span_err(
|
||||
positions,
|
||||
"generic arguments must declare lifetimes, types and associated type bindings in \
|
||||
that order",
|
||||
)
|
||||
} else if !bad_lifetime_pos.is_empty() {
|
||||
self.struct_span_err(
|
||||
bad_lifetime_pos.clone(),
|
||||
"lifetime parameters must be declared prior to type parameters"
|
||||
);
|
||||
)
|
||||
} else if !bad_type_pos.is_empty() {
|
||||
self.struct_span_err(
|
||||
bad_type_pos.clone(),
|
||||
"type parameters must be declared prior to associated type bindings"
|
||||
)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !bad_lifetime_pos.is_empty() {
|
||||
for sp in &bad_lifetime_pos {
|
||||
err.span_label(*sp, "must be declared prior to type parameters");
|
||||
}
|
||||
if !lifetime_suggestions.is_empty() {
|
||||
err.multipart_suggestion_with_applicability(
|
||||
&format!(
|
||||
"move the lifetime parameter{} prior to the first type parameter",
|
||||
if bad_lifetime_pos.len() > 1 { "s" } else { "" },
|
||||
),
|
||||
lifetime_suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
if !bad_type_pos.is_empty() {
|
||||
let mut err = self.struct_span_err(
|
||||
bad_type_pos.clone(),
|
||||
"type parameters must be declared prior to associated type bindings"
|
||||
);
|
||||
for sp in &bad_type_pos {
|
||||
err.span_label(*sp, "must be declared prior to associated type bindings");
|
||||
}
|
||||
if !type_suggestions.is_empty() {
|
||||
err.multipart_suggestion_with_applicability(
|
||||
&format!(
|
||||
"move the type parameter{} prior to the first associated type binding",
|
||||
if bad_type_pos.len() > 1 { "s" } else { "" },
|
||||
),
|
||||
type_suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
Ok((args, bindings))
|
||||
if !lifetime_suggestions.is_empty() && !type_suggestions.is_empty() {
|
||||
let mut suggestions = lifetime_suggestions;
|
||||
suggestions.extend_from_slice(&type_suggestions);
|
||||
|
||||
let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1;
|
||||
err.multipart_suggestion_with_applicability(
|
||||
&format!(
|
||||
"move the parameter{}",
|
||||
if plural { "s" } else { "" },
|
||||
),
|
||||
suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if !lifetime_suggestions.is_empty() {
|
||||
err.multipart_suggestion_with_applicability(
|
||||
&format!(
|
||||
"move the lifetime parameter{} prior to the first type parameter",
|
||||
if bad_lifetime_pos.len() > 1 { "s" } else { "" },
|
||||
),
|
||||
lifetime_suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if !type_suggestions.is_empty() {
|
||||
err.multipart_suggestion_with_applicability(
|
||||
&format!(
|
||||
"move the type parameter{} prior to the first associated type binding",
|
||||
if bad_type_pos.len() > 1 { "s" } else { "" },
|
||||
),
|
||||
type_suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
/// Parses an optional `where` clause and places it in `generics`.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
#![allow(warnings)]
|
||||
|
||||
// This test verifies that the suggestion to move types before associated type bindings
|
||||
|
@ -7,17 +9,34 @@ trait One<T> {
|
|||
type A;
|
||||
}
|
||||
|
||||
trait OneWithLifetime<'a, T> {
|
||||
type A;
|
||||
}
|
||||
|
||||
trait Three<T, U, V> {
|
||||
type A;
|
||||
type B;
|
||||
type C;
|
||||
}
|
||||
|
||||
trait ThreeWithLifetime<'a, 'b, 'c, T, U, V> {
|
||||
type A;
|
||||
type B;
|
||||
type C;
|
||||
}
|
||||
|
||||
struct A<T, M: One<A=(), T>> { //~ ERROR type parameters must be declared
|
||||
m: M,
|
||||
t: T,
|
||||
}
|
||||
|
||||
|
||||
struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
|
||||
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
m: M,
|
||||
t: &'a T,
|
||||
}
|
||||
|
||||
struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type parameters must be declared
|
||||
m: M,
|
||||
t: T,
|
||||
|
@ -25,6 +44,14 @@ struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type paramete
|
|||
v: V,
|
||||
}
|
||||
|
||||
struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
|
||||
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
m: M,
|
||||
t: &'a T,
|
||||
u: &'b U,
|
||||
v: &'c V,
|
||||
}
|
||||
|
||||
struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type parameters must be declared
|
||||
m: M,
|
||||
t: T,
|
||||
|
@ -32,6 +59,14 @@ struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type paramete
|
|||
v: V,
|
||||
}
|
||||
|
||||
struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
|
||||
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
m: M,
|
||||
t: &'a T,
|
||||
u: &'b U,
|
||||
v: &'c V,
|
||||
}
|
||||
|
||||
struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type parameters must be declared
|
||||
m: M,
|
||||
t: T,
|
||||
|
@ -39,4 +74,12 @@ struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type paramete
|
|||
v: V,
|
||||
}
|
||||
|
||||
struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
|
||||
//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
m: M,
|
||||
t: &'a T,
|
||||
u: &'b U,
|
||||
v: &'c V,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: type parameters must be declared prior to associated type bindings
|
||||
--> $DIR/suggest-move-types.rs:16:26
|
||||
--> $DIR/suggest-move-types.rs:28:26
|
||||
|
|
||||
LL | struct A<T, M: One<A=(), T>> { //~ ERROR type parameters must be declared
|
||||
| ^ must be declared prior to associated type bindings
|
||||
|
@ -8,8 +8,20 @@ help: move the type parameter prior to the first associated type binding
|
|||
LL | struct A<T, M: One<T, A=()>> { //~ ERROR type parameters must be declared
|
||||
| ^^ --
|
||||
|
||||
error: generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
--> $DIR/suggest-move-types.rs:34:46
|
||||
|
|
||||
LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
|
||||
| ^ ^^ must be declared prior to type parameters
|
||||
| |
|
||||
| must be declared prior to associated type bindings
|
||||
help: move the parameters
|
||||
|
|
||||
LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A=()>> {
|
||||
| ^^^ ^^ --
|
||||
|
||||
error: type parameters must be declared prior to associated type bindings
|
||||
--> $DIR/suggest-move-types.rs:21:46
|
||||
--> $DIR/suggest-move-types.rs:40:46
|
||||
|
|
||||
LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type parameters must be declared
|
||||
| ^ ^ ^ must be declared prior to associated type bindings
|
||||
|
@ -21,8 +33,24 @@ help: move the type parameters prior to the first associated type binding
|
|||
LL | struct B<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
|
||||
| ^^ ^^ ^^ --
|
||||
|
||||
error: generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
--> $DIR/suggest-move-types.rs:47:80
|
||||
|
|
||||
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
|
||||
| ^ ^ ^ ^^ ^^ ^^ must be declared prior to type parameters
|
||||
| | | | | |
|
||||
| | | | | must be declared prior to type parameters
|
||||
| | | | must be declared prior to type parameters
|
||||
| | | must be declared prior to associated type bindings
|
||||
| | must be declared prior to associated type bindings
|
||||
| must be declared prior to associated type bindings
|
||||
help: move the parameters
|
||||
|
|
||||
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
|
||||
| ^^^ ^^^ ^^^ ^^ ^^ ^^ --
|
||||
|
||||
error: type parameters must be declared prior to associated type bindings
|
||||
--> $DIR/suggest-move-types.rs:28:49
|
||||
--> $DIR/suggest-move-types.rs:55:49
|
||||
|
|
||||
LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type parameters must be declared
|
||||
| ^ ^ must be declared prior to associated type bindings
|
||||
|
@ -33,8 +61,23 @@ help: move the type parameters prior to the first associated type binding
|
|||
LL | struct C<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
|
||||
| ^^ ^^ --
|
||||
|
||||
error: generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
--> $DIR/suggest-move-types.rs:62:56
|
||||
|
|
||||
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
|
||||
| ^^ ^ ^^ ^ ^^ must be declared prior to type parameters
|
||||
| | | | |
|
||||
| | | | must be declared prior to associated type bindings
|
||||
| | | must be declared prior to type parameters
|
||||
| | must be declared prior to associated type bindings
|
||||
| must be declared prior to type parameters
|
||||
help: move the parameters
|
||||
|
|
||||
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
|
||||
| ^^^ ^^^ ^^^ -- ^^ ^^ --
|
||||
|
||||
error: type parameters must be declared prior to associated type bindings
|
||||
--> $DIR/suggest-move-types.rs:35:43
|
||||
--> $DIR/suggest-move-types.rs:70:43
|
||||
|
|
||||
LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type parameters must be declared
|
||||
| ^ ^ must be declared prior to associated type bindings
|
||||
|
@ -45,5 +88,20 @@ help: move the type parameters prior to the first associated type binding
|
|||
LL | struct D<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
|
||||
| ^^ ^^ -- --
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: generic arguments must declare lifetimes, types and associated type bindings in that order
|
||||
--> $DIR/suggest-move-types.rs:77:56
|
||||
|
|
||||
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
|
||||
| ^^ ^ ^^ ^ ^^ must be declared prior to type parameters
|
||||
| | | | |
|
||||
| | | | must be declared prior to associated type bindings
|
||||
| | | must be declared prior to type parameters
|
||||
| | must be declared prior to associated type bindings
|
||||
| must be declared prior to type parameters
|
||||
help: move the parameters
|
||||
|
|
||||
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
|
||||
| ^^^ ^^^ ^^^ -- ^^ ^^ -- --
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue