Skip to content

Commit

Permalink
Fix suggestions given mulitple bad lifetimes
Browse files Browse the repository at this point in the history
When given multiple lifetimes prior to type parameters in generic
parameters, do not ICE and print the correct suggestion.
  • Loading branch information
dlrobertson committed Jan 18, 2019
1 parent e2f221c commit e3ba6ed
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 21 deletions.
9 changes: 5 additions & 4 deletions src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,11 @@ impl CodeSuggestion {
if let Some(line) = line_opt {
if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) {
let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi));
buf.push_str(match hi_opt {
Some(hi) => &line[lo..hi],
None => &line[lo..],
});
match hi_opt {
Some(hi) if hi > lo => buf.push_str(&line[lo..hi]),
Some(_) => (),
None => buf.push_str(&line[lo..]),
}
}
if let None = hi_opt {
buf.push('\n');
Expand Down
21 changes: 6 additions & 15 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5234,22 +5234,13 @@ impl<'a> Parser<'a> {
kind: ast::GenericParamKind::Lifetime,
});
if let Some(sp) = seen_ty_param {
let param_span = self.prev_span;
let ate_comma = self.eat(&token::Comma);
let remove_sp = if ate_comma {
param_span.until(self.span)
} else {
last_comma_span.unwrap_or(param_span).to(param_span)
};
bad_lifetime_pos.push(param_span);

if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span);
bad_lifetime_pos.push(self.prev_span);
if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) {
suggestions.push((remove_sp, String::new()));
suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
}
if ate_comma {
last_comma_span = Some(self.prev_span);
continue
suggestions.push((
sp.shrink_to_lo(),
format!("{}, ", snippet)));
}
}
} else if self.check_ident() {
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/lifetime-before-type-params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![allow(unused)]
fn first<T, 'a, 'b>() {}
//~^ ERROR lifetime parameters must be declared prior to type parameters
fn second<'a, T, 'b>() {}
//~^ ERROR lifetime parameters must be declared prior to type parameters
fn third<T, U, 'a>() {}
//~^ ERROR lifetime parameters must be declared prior to type parameters
fn fourth<'a, T, 'b, U, 'c, V>() {}
//~^ ERROR lifetime parameters must be declared prior to type parameters
47 changes: 47 additions & 0 deletions src/test/ui/lifetime-before-type-params.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:2:13
|
LL | fn first<T, 'a, 'b>() {}
| ^^ ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | fn first<'a, 'b, T>() {}
| ^^^ ^^^ --

error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:4:18
|
LL | fn second<'a, T, 'b>() {}
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | fn second<'a, 'b, T>() {}
| ^^^ --

error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:6:16
|
LL | fn third<T, U, 'a>() {}
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | fn third<'a, T, U>() {}
| ^^^ --

error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:8:18
|
LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
| ^^ ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | fn fourth<'a, 'b, 'c, T, U, V>() {}
| ^^^ ^^^ -- --

error[E0601]: `main` function not found in crate `lifetime_before_type_params`
|
= note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs`

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0601`.
4 changes: 2 additions & 2 deletions src/test/ui/suggestions/suggest-move-lifetimes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ LL | struct B<T, 'a, U> { //~ ERROR lifetime parameters must be declared
help: move the lifetime parameter prior to the first type parameter
|
LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared
| ^^^ --
| ^^^ --

error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:10:16
Expand All @@ -36,7 +36,7 @@ LL | struct D<T, U, 'a, 'b, V, 'c> { //~ ERROR lifetime parameters must be decla
help: move the lifetime parameter prior to the first type parameter
|
LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared
| ^^^ ^^^ ^^^ ---
| ^^^ ^^^ ^^^ -- --

error: aborting due to 4 previous errors

0 comments on commit e3ba6ed

Please sign in to comment.