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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue