Emit one diagnostic for multiple misplaced lifetimes

This commit is contained in:
Esteban Küber 2018-11-26 08:32:47 -08:00
parent 234d043d18
commit 45dfe43887
3 changed files with 38 additions and 15 deletions

View file

@ -5182,6 +5182,8 @@ impl<'a> Parser<'a> {
let mut params = Vec::new();
let mut seen_ty_param: Option<Span> = None;
let mut last_comma_span = None;
let mut bad_lifetime_pos = vec![];
let mut suggestions = vec![];
loop {
let attrs = self.parse_outer_attributes()?;
if self.check_lifetime() {
@ -5207,20 +5209,12 @@ impl<'a> Parser<'a> {
} else {
last_comma_span.unwrap_or(param_span).to(param_span)
};
let mut err = self.struct_span_err(
self.prev_span,
"lifetime parameters must be declared prior to type parameters",
);
bad_lifetime_pos.push(param_span);
if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
err.multipart_suggestion(
"move the lifetime parameter prior to the first type parameter",
vec![
(remove_sp, String::new()),
(sp.shrink_to_lo(), format!("{}, ", snippet)),
],
);
suggestions.push((remove_sp, String::new()));
suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
}
err.emit();
if ate_comma {
last_comma_span = Some(self.prev_span);
continue
@ -5247,6 +5241,19 @@ impl<'a> Parser<'a> {
}
last_comma_span = Some(self.prev_span);
}
if !bad_lifetime_pos.is_empty() {
let mut err = self.struct_span_err(
bad_lifetime_pos,
"lifetime parameters must be declared prior to type parameters",
);
if !suggestions.is_empty() {
err.multipart_suggestion(
"move the lifetime parameter prior to the first type parameter",
suggestions,
);
}
err.emit();
}
lifetimes.extend(params); // ensure the correct order of lifetimes and type params
Ok(lifetimes)
}

View file

@ -12,4 +12,10 @@ struct C<T, U, 'a> {
u: U,
}
struct D<T, U, 'a, 'b, V, 'c> {
t: &'a T,
u: &'b U,
v: &'c V,
}
fn main() {}

View file

@ -9,10 +9,10 @@ LL | struct A<'a, T> {
| ^^^ --
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:5:15
--> $DIR/suggest-move-lifetimes.rs:5:13
|
LL | struct B<T, 'a, U> {
| ^
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct B<'a, T, U> {
@ -28,5 +28,15 @@ help: move the lifetime parameter prior to the first type parameter
LL | struct C<'a, T, U> {
| ^^^ --
error: aborting due to 3 previous errors
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:15:16
|
LL | struct D<T, U, 'a, 'b, V, 'c> {
| ^^ ^^ ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct D<'a, 'b, 'c, T, U, V> {
| ^^^ ^^^ ^^^ ---
error: aborting due to 4 previous errors