Skip to content

Commit e3ba6ed

Browse files
committed
Fix suggestions given mulitple bad lifetimes
When given multiple lifetimes prior to type parameters in generic parameters, do not ICE and print the correct suggestion.
1 parent e2f221c commit e3ba6ed

File tree

5 files changed

+69
-21
lines changed

5 files changed

+69
-21
lines changed

src/librustc_errors/lib.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,11 @@ impl CodeSuggestion {
135135
if let Some(line) = line_opt {
136136
if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) {
137137
let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi));
138-
buf.push_str(match hi_opt {
139-
Some(hi) => &line[lo..hi],
140-
None => &line[lo..],
141-
});
138+
match hi_opt {
139+
Some(hi) if hi > lo => buf.push_str(&line[lo..hi]),
140+
Some(_) => (),
141+
None => buf.push_str(&line[lo..]),
142+
}
142143
}
143144
if let None = hi_opt {
144145
buf.push('\n');

src/libsyntax/parse/parser.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -5234,22 +5234,13 @@ impl<'a> Parser<'a> {
52345234
kind: ast::GenericParamKind::Lifetime,
52355235
});
52365236
if let Some(sp) = seen_ty_param {
5237-
let param_span = self.prev_span;
5238-
let ate_comma = self.eat(&token::Comma);
5239-
let remove_sp = if ate_comma {
5240-
param_span.until(self.span)
5241-
} else {
5242-
last_comma_span.unwrap_or(param_span).to(param_span)
5243-
};
5244-
bad_lifetime_pos.push(param_span);
5245-
5246-
if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
5237+
let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span);
5238+
bad_lifetime_pos.push(self.prev_span);
5239+
if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) {
52475240
suggestions.push((remove_sp, String::new()));
5248-
suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
5249-
}
5250-
if ate_comma {
5251-
last_comma_span = Some(self.prev_span);
5252-
continue
5241+
suggestions.push((
5242+
sp.shrink_to_lo(),
5243+
format!("{}, ", snippet)));
52535244
}
52545245
}
52555246
} else if self.check_ident() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![allow(unused)]
2+
fn first<T, 'a, 'b>() {}
3+
//~^ ERROR lifetime parameters must be declared prior to type parameters
4+
fn second<'a, T, 'b>() {}
5+
//~^ ERROR lifetime parameters must be declared prior to type parameters
6+
fn third<T, U, 'a>() {}
7+
//~^ ERROR lifetime parameters must be declared prior to type parameters
8+
fn fourth<'a, T, 'b, U, 'c, V>() {}
9+
//~^ ERROR lifetime parameters must be declared prior to type parameters
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error: lifetime parameters must be declared prior to type parameters
2+
--> $DIR/lifetime-before-type-params.rs:2:13
3+
|
4+
LL | fn first<T, 'a, 'b>() {}
5+
| ^^ ^^
6+
help: move the lifetime parameter prior to the first type parameter
7+
|
8+
LL | fn first<'a, 'b, T>() {}
9+
| ^^^ ^^^ --
10+
11+
error: lifetime parameters must be declared prior to type parameters
12+
--> $DIR/lifetime-before-type-params.rs:4:18
13+
|
14+
LL | fn second<'a, T, 'b>() {}
15+
| ^^
16+
help: move the lifetime parameter prior to the first type parameter
17+
|
18+
LL | fn second<'a, 'b, T>() {}
19+
| ^^^ --
20+
21+
error: lifetime parameters must be declared prior to type parameters
22+
--> $DIR/lifetime-before-type-params.rs:6:16
23+
|
24+
LL | fn third<T, U, 'a>() {}
25+
| ^^
26+
help: move the lifetime parameter prior to the first type parameter
27+
|
28+
LL | fn third<'a, T, U>() {}
29+
| ^^^ --
30+
31+
error: lifetime parameters must be declared prior to type parameters
32+
--> $DIR/lifetime-before-type-params.rs:8:18
33+
|
34+
LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
35+
| ^^ ^^
36+
help: move the lifetime parameter prior to the first type parameter
37+
|
38+
LL | fn fourth<'a, 'b, 'c, T, U, V>() {}
39+
| ^^^ ^^^ -- --
40+
41+
error[E0601]: `main` function not found in crate `lifetime_before_type_params`
42+
|
43+
= note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs`
44+
45+
error: aborting due to 5 previous errors
46+
47+
For more information about this error, try `rustc --explain E0601`.

src/test/ui/suggestions/suggest-move-lifetimes.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL | struct B<T, 'a, U> { //~ ERROR lifetime parameters must be declared
1616
help: move the lifetime parameter prior to the first type parameter
1717
|
1818
LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared
19-
| ^^^ --
19+
| ^^^ --
2020

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

4141
error: aborting due to 4 previous errors
4242

0 commit comments

Comments
 (0)