Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Emit one diagnostic for multiple misplaced lifetimes
  • Loading branch information
estebank committed Nov 26, 2018
1 parent 234d043 commit 45dfe43
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
31 changes: 19 additions & 12 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -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() {
Expand All @@ -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
Expand All @@ -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)
}
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/suggestions/suggest-move-lifetimes.rs
Expand Up @@ -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() {}
16 changes: 13 additions & 3 deletions src/test/ui/suggestions/suggest-move-lifetimes.stderr
Expand Up @@ -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> {
Expand All @@ -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

0 comments on commit 45dfe43

Please sign in to comment.