diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index a074441f8a179..3e25f98ccd27c 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -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'); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 823c786bded26..5b430d13516b4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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() { diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs new file mode 100644 index 0000000000000..9b905d4883a16 --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.rs @@ -0,0 +1,9 @@ +#![allow(unused)] +fn first() {} +//~^ 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() {} +//~^ 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 diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr new file mode 100644 index 0000000000000..7ac8dffdfbe0c --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.stderr @@ -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() {} + | ^^ ^^ +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() {} + | ^^ +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`. diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index 72a2cbe6bf6de..b36e927b5c0c6 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -16,7 +16,7 @@ LL | struct B { //~ 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 @@ -36,7 +36,7 @@ LL | struct D { //~ 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