diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-14 20:31:55 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-14 20:31:55 +0100 |
| commit | 2f7a226c4dfd8fe71a7451063b6724166b705cf2 (patch) | |
| tree | 379e29c97d1847840c5b054f516d3ea71e85a8da /src | |
| parent | 816e31b1c608626f1a67387676f85544f3da843d (diff) | |
| parent | 28ea03e11477032a29b30284487d6d73e181ecaf (diff) | |
| download | rust-2f7a226c4dfd8fe71a7451063b6724166b705cf2.tar.gz rust-2f7a226c4dfd8fe71a7451063b6724166b705cf2.zip | |
Rollup merge of #57540 - estebank:eval-more, r=petrochenkov
Modify some parser diagnostics to continue evaluating beyond the parser Continue evaluating further errors after parser errors on: - trailing type argument attribute - lifetime in incorrect location - incorrect binary literal - missing `for` in `impl Trait for Foo` - type argument in `where` clause - incorrect float literal - incorrect `..` in pattern - associated types - incorrect discriminator value variant error and others. All of these were found by making `continue-parse-after-error` `true` by default to identify errors that would need few changes. There are now only a handful of errors that have any change with `continue-parse-after-error` enabled. These changes make it so `rust` _won't_ stop evaluation after finishing parsing, enabling type checking errors to be displayed on the existing code without having to fix the parse errors. Each commit has an individual diagnostic change with their corresponding tests. CC #48724.
Diffstat (limited to 'src')
41 files changed, 344 insertions, 141 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ecb34e43c59..0e1c3b4b61f 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -299,7 +299,7 @@ impl<'a> StringReader<'a> { /// Report a lexical error with a given span. fn err_span(&self, sp: Span, m: &str) { - self.sess.span_diagnostic.span_err(sp, m) + self.sess.span_diagnostic.struct_span_err(sp, m).emit(); } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ba5676a65d7..ea205530ca5 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -520,6 +520,7 @@ fn filtered_float_lit(data: Symbol, suffix: Option<Symbol>, diag: Option<(Span, } else { let msg = format!("invalid suffix `{}` for float literal", suf); diag.struct_span_err(span, &msg) + .span_label(span, format!("invalid suffix `{}`", suf)) .help("valid suffixes are `f32` and `f64`") .emit(); } @@ -673,7 +674,11 @@ fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>) _ => None, }; if let Some(err) = err { - err!(diag, |span, diag| diag.span_err(span, err)); + err!(diag, |span, diag| { + diag.struct_span_err(span, err) + .span_label(span, "not supported") + .emit(); + }); } return filtered_float_lit(Symbol::intern(s), Some(suf), diag) } @@ -712,6 +717,7 @@ fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>) } else { let msg = format!("invalid suffix `{}` for numeric literal", suf); diag.struct_span_err(span, &msg) + .span_label(span, format!("invalid suffix `{}`", suf)) .help("the suffix must be one of the integral types \ (`u32`, `isize`, etc)") .emit(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5c8ed94731a..06ba3bbd402 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1012,7 +1012,10 @@ impl<'a> Parser<'a> { if text.is_empty() { self.span_bug(sp, "found empty literal suffix in Some") } - self.span_err(sp, &format!("{} with a suffix is invalid", kind)); + let msg = format!("{} with a suffix is invalid", kind); + self.struct_span_err(sp, &msg) + .span_label(sp, msg) + .emit(); } } } @@ -1768,9 +1771,11 @@ impl<'a> Parser<'a> { Mutability::Immutable } else { let span = self.prev_span; - self.span_err(span, - "expected mut or const in raw pointer type (use \ - `*mut T` or `*const T` as appropriate)"); + let msg = "expected mut or const in raw pointer type"; + self.struct_span_err(span, msg) + .span_label(span, msg) + .help("use `*mut T` or `*const T` as appropriate") + .emit(); Mutability::Immutable }; let t = self.parse_ty_no_plus()?; @@ -3815,8 +3820,12 @@ impl<'a> Parser<'a> { ddpos = Some(fields.len()); } else { // Emit a friendly error, ignore `..` and continue parsing - self.span_err(self.prev_span, - "`..` can only be used once per tuple or tuple struct pattern"); + self.struct_span_err( + self.prev_span, + "`..` can only be used once per tuple or tuple struct pattern", + ) + .span_label(self.prev_span, "can only be used once per pattern") + .emit(); } } else if !self.check(&token::CloseDelim(token::Paren)) { fields.push(self.parse_pat(None)?); @@ -3832,7 +3841,10 @@ impl<'a> Parser<'a> { if ddpos == Some(fields.len()) && trailing_comma { // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed. - self.span_err(self.prev_span, "trailing comma is not permitted after `..`"); + let msg = "trailing comma is not permitted after `..`"; + self.struct_span_err(self.prev_span, msg) + .span_label(self.prev_span, msg) + .emit(); } Ok((fields, ddpos, trailing_comma)) @@ -5256,8 +5268,12 @@ impl<'a> Parser<'a> { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" }; - self.span_err(attrs[0].span, - &format!("trailing attribute after {} parameters", param_kind)); + self.struct_span_err( + attrs[0].span, + &format!("trailing attribute after {} parameters", param_kind), + ) + .span_label(attrs[0].span, "attributes must go before parameters") + .emit(); } break } @@ -5315,19 +5331,28 @@ impl<'a> Parser<'a> { /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, /// possibly including trailing comma. - fn parse_generic_args(&mut self) - -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> { + fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> { let mut args = Vec::new(); let mut bindings = Vec::new(); let mut seen_type = false; let mut seen_binding = false; + let mut first_type_or_binding_span: Option<Span> = None; + let mut bad_lifetime_pos = vec![]; + let mut last_comma_span = None; + let mut suggestions = vec![]; loop { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. args.push(GenericArg::Lifetime(self.expect_lifetime())); if seen_type || seen_binding { - self.span_err(self.prev_span, - "lifetime parameters must be declared prior to type parameters"); + 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(( + first_type_or_binding_span.unwrap().shrink_to_lo(), + format!("{}, ", snippet))); + } } } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { // Parse associated type binding. @@ -5335,19 +5360,33 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; self.bump(); let ty = self.parse_ty()?; + let span = lo.to(self.prev_span); bindings.push(TypeBinding { id: ast::DUMMY_NODE_ID, ident, ty, - span: lo.to(self.prev_span), + span, }); seen_binding = true; + if first_type_or_binding_span.is_none() { + first_type_or_binding_span = Some(span); + } } else if self.check_type() { // Parse type argument. let ty_param = self.parse_ty()?; if seen_binding { - self.span_err(ty_param.span, - "type parameters must be declared prior to associated type bindings"); + self.struct_span_err( + ty_param.span, + "type parameters must be declared prior to associated type bindings" + ) + .span_label( + ty_param.span, + "must be declared prior to associated type bindings", + ) + .emit(); + } + if first_type_or_binding_span.is_none() { + first_type_or_binding_span = Some(ty_param.span); } args.push(GenericArg::Type(ty_param)); seen_type = true; @@ -5357,7 +5396,29 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break + } else { + last_comma_span = Some(self.prev_span); + } + } + if !bad_lifetime_pos.is_empty() { + let mut err = self.struct_span_err( + bad_lifetime_pos.clone(), + "lifetime parameters must be declared prior to type parameters" + ); + for sp in &bad_lifetime_pos { + err.span_label(*sp, "must be declared prior to type parameters"); + } + if !suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + &format!( + "move the lifetime parameter{} prior to the first type parameter", + if bad_lifetime_pos.len() > 1 { "s" } else { "" }, + ), + suggestions, + Applicability::MachineApplicable, + ); } + err.emit(); } Ok((args, bindings)) } @@ -5386,8 +5447,12 @@ impl<'a> Parser<'a> { // change we parse those generics now, but report an error. if self.choose_generics_over_qpath() { let generics = self.parse_generics()?; - self.span_err(generics.span, - "generic parameters on `where` clauses are reserved for future use"); + self.struct_span_err( + generics.span, + "generic parameters on `where` clauses are reserved for future use", + ) + .span_label(generics.span, "currently unsupported") + .emit(); } loop { @@ -5587,15 +5652,20 @@ impl<'a> Parser<'a> { // *mut self // *not_self // Emit special error for `self` cases. + let msg = "cannot pass `self` by raw pointer"; (if isolated_self(self, 1) { self.bump(); - self.span_err(self.span, "cannot pass `self` by raw pointer"); + self.struct_span_err(self.span, msg) + .span_label(self.span, msg) + .emit(); SelfKind::Value(Mutability::Immutable) } else if self.look_ahead(1, |t| t.is_mutability()) && isolated_self(self, 2) { self.bump(); self.bump(); - self.span_err(self.span, "cannot pass `self` by raw pointer"); + self.struct_span_err(self.span, msg) + .span_label(self.span, msg) + .emit(); SelfKind::Value(Mutability::Immutable) } else { return Ok(None); @@ -5932,7 +6002,10 @@ impl<'a> Parser<'a> { tps.where_clause = self.parse_where_clause()?; self.expect(&token::Semi)?; if unsafety != Unsafety::Normal { - self.span_err(self.prev_span, "trait aliases cannot be unsafe"); + let msg = "trait aliases cannot be unsafe"; + self.struct_span_err(self.prev_span, msg) + .span_label(self.prev_span, msg) + .emit(); } Ok((ident, ItemKind::TraitAlias(tps, bounds), None)) } else { @@ -6048,7 +6121,13 @@ impl<'a> Parser<'a> { Some(ty_second) => { // impl Trait for Type if !has_for { - self.span_err(missing_for_span, "missing `for` in a trait impl"); + self.struct_span_err(missing_for_span, "missing `for` in a trait impl") + .span_suggestion_short_with_applicability( + missing_for_span, + "add `for` here", + " for ".to_string(), + Applicability::MachineApplicable, + ).emit(); } let ty_first = ty_first.into_inner(); @@ -6939,7 +7018,7 @@ impl<'a> Parser<'a> { fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> { let mut variants = Vec::new(); let mut all_nullary = true; - let mut any_disr = None; + let mut any_disr = vec![]; while self.token != token::CloseDelim(token::Brace) { let variant_attrs = self.parse_outer_attributes()?; let vlo = self.span; @@ -6961,7 +7040,9 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, value: self.parse_expr()?, }); - any_disr = disr_expr.as_ref().map(|c| c.value.span); + if let Some(sp) = disr_expr.as_ref().map(|c| c.value.span) { + any_disr.push(sp); + } struct_def = VariantData::Unit(ast::DUMMY_NODE_ID); } else { struct_def = VariantData::Unit(ast::DUMMY_NODE_ID); @@ -6978,11 +7059,15 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break; } } self.expect(&token::CloseDelim(token::Brace))?; - match any_disr { - Some(disr_span) if !all_nullary => - self.span_err(disr_span, - "discriminator values can only be used with a field-less enum"), - _ => () + if !any_disr.is_empty() && !all_nullary { + let mut err =self.struct_span_err( + any_disr.clone(), + "discriminator values can only be used with a field-less enum", + ); + for sp in any_disr { + err.span_label(sp, "only valid in field-less enums"); + } + err.emit(); } Ok(ast::EnumDef { variants }) diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr index 75c0d91ee17..c4c0cee5ccc 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-1.stderr @@ -2,7 +2,7 @@ error: trailing attribute after lifetime parameters --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25 | LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { - | ^^^^^^^ + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr index 7585c6dd738..9099d74ce1b 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-2.stderr @@ -2,7 +2,7 @@ error: trailing attribute after type parameters --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35 | LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} - | ^^^^^^^ + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs index 343a2d7a563..e9f908d479f 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.rs @@ -5,12 +5,8 @@ struct RefIntPair<'a, 'b>(&'a u32, &'b u32); fn hof_lt<Q>(_: Q) - where Q: for <#[rustc_1] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 + where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 //~^ ERROR trailing attribute after lifetime parameters -{ +{} -} - -fn main() { - -} +fn main() {} diff --git a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr index 91960510de4..452f0ea5e17 100644 --- a/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr +++ b/src/test/ui/attrs-with-no-formal-in-generics/attrs-with-no-formal-in-generics-3.stderr @@ -1,8 +1,8 @@ error: trailing attribute after lifetime parameters - --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:38 + --> $DIR/attrs-with-no-formal-in-generics-3.rs:8:44 | -LL | where Q: for <#[rustc_1] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 - | ^^^^^^^ +LL | where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 + | ^^^^^^^ attributes must go before parameters error: aborting due to previous error diff --git a/src/test/ui/old-suffixes-are-really-forbidden.stderr b/src/test/ui/old-suffixes-are-really-forbidden.stderr index 557e7ef6794..c54b72a3585 100644 --- a/src/test/ui/old-suffixes-are-really-forbidden.stderr +++ b/src/test/ui/old-suffixes-are-really-forbidden.stderr @@ -2,7 +2,7 @@ error: invalid suffix `is` for numeric literal --> $DIR/old-suffixes-are-really-forbidden.rs:2:13 | LL | let a = 1_is; //~ ERROR invalid suffix - | ^^^^ + | ^^^^ invalid suffix `is` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) @@ -10,7 +10,7 @@ error: invalid suffix `us` for numeric literal --> $DIR/old-suffixes-are-really-forbidden.rs:3:13 | LL | let b = 2_us; //~ ERROR invalid suffix - | ^^^^ + | ^^^^ invalid suffix `us` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr index 4fd2ab8177b..608c5fda248 100644 --- a/src/test/ui/parser/bad-lit-suffixes.stderr +++ b/src/test/ui/parser/bad-lit-suffixes.stderr @@ -2,49 +2,49 @@ error: ABI spec with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:5:5 | LL | "C"suffix //~ ERROR ABI spec with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ ABI spec with a suffix is invalid error: ABI spec with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:9:5 | LL | "C"suffix //~ ERROR ABI spec with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ ABI spec with a suffix is invalid error: string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:13:5 | LL | ""suffix; //~ ERROR string literal with a suffix is invalid - | ^^^^^^^^ + | ^^^^^^^^ string literal with a suffix is invalid error: byte string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:14:5 | LL | b""suffix; //~ ERROR byte string literal with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ byte string literal with a suffix is invalid error: string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:15:5 | LL | r#""#suffix; //~ ERROR string literal with a suffix is invalid - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ string literal with a suffix is invalid error: byte string literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:16:5 | LL | br#""#suffix; //~ ERROR byte string literal with a suffix is invalid - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ byte string literal with a suffix is invalid error: char literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:17:5 | LL | 'a'suffix; //~ ERROR char literal with a suffix is invalid - | ^^^^^^^^^ + | ^^^^^^^^^ char literal with a suffix is invalid error: byte literal with a suffix is invalid --> $DIR/bad-lit-suffixes.rs:18:5 | LL | b'a'suffix; //~ ERROR byte literal with a suffix is invalid - | ^^^^^^^^^^ + | ^^^^^^^^^^ byte literal with a suffix is invalid error: invalid width `1024` for integer literal --> $DIR/bad-lit-suffixes.rs:20:5 @@ -82,7 +82,7 @@ error: invalid suffix `suffix` for numeric literal --> $DIR/bad-lit-suffixes.rs:25:5 | LL | 1234suffix; //~ ERROR invalid suffix `suffix` for numeric literal - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid suffix `suffix` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) @@ -90,7 +90,7 @@ error: invalid suffix `suffix` for numeric literal --> $DIR/bad-lit-suffixes.rs:26:5 | LL | 0b101suffix; //~ ERROR invalid suffix `suffix` for numeric literal - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ invalid suffix `suffix` | = help: the suffix must be one of the integral types (`u32`, `isize`, etc) @@ -98,7 +98,7 @@ error: invalid suffix `suffix` for float literal --> $DIR/bad-lit-suffixes.rs:27:5 | LL | 1.0suffix; //~ ERROR invalid suffix `suffix` for float literal - | ^^^^^^^^^ + | ^^^^^^^^^ invalid suffix `suffix` | = help: valid suffixes are `f32` and `f64` @@ -106,7 +106,7 @@ error: invalid suffix `suffix` for float literal --> $DIR/bad-lit-suffixes.rs:28:5 | LL | 1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ invalid suffix `suffix` | = help: valid suffixes are `f32` and `f64` diff --git a/src/test/ui/parser/bad-pointer-type.rs b/src/test/ui/parser/bad-pointer-type.rs index 0e5a01103dc..59e5e0c5d31 100644 --- a/src/test/ui/parser/bad-pointer-type.rs +++ b/src/test/ui/parser/bad-pointer-type.rs @@ -1,5 +1,5 @@ fn foo(_: *()) { - //~^ expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) + //~^ ERROR expected mut or const in raw pointer type } fn main() {} diff --git a/src/test/ui/parser/bad-pointer-type.stderr b/src/test/ui/parser/bad-pointer-type.stderr index 860f9f96bb8..e18c220affe 100644 --- a/src/test/ui/parser/bad-pointer-type.stderr +++ b/src/test/ui/parser/bad-pointer-type.stderr @@ -1,8 +1,10 @@ -error: expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) +error: expected mut or const in raw pointer type --> $DIR/bad-pointer-type.rs:1:11 | LL | fn foo(_: *()) { - | ^ + | ^ expected mut or const in raw pointer type + | + = help: use `*mut T` or `*const T` as appropriate error: aborting due to previous error diff --git a/src/test/ui/parser/impl-parsing.stderr b/src/test/ui/parser/impl-parsing.stderr index 308f14c60c7..353f5e21ee6 100644 --- a/src/test/ui/parser/impl-parsing.stderr +++ b/src/test/ui/parser/impl-parsing.stderr @@ -2,13 +2,13 @@ error: missing `for` in a trait impl --> $DIR/impl-parsing.rs:6:11 | LL | impl Trait Type {} //~ ERROR missing `for` in a trait impl - | ^ + | ^ help: add `for` here error: missing `for` in a trait impl --> $DIR/impl-parsing.rs:7:11 | LL | impl Trait .. {} //~ ERROR missing `for` in a trait impl - | ^ + | ^ help: add `for` here error: expected a trait, found type --> $DIR/impl-parsing.rs:8:6 diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs index f5894349e15..17b9b766b21 100644 --- a/src/test/ui/parser/issue-14303-fncall.rs +++ b/src/test/ui/parser/issue-14303-fncall.rs @@ -1,6 +1,17 @@ -fn main() { - (0..4) - .map(|x| x * 2) - .collect::<Vec<'a, usize, 'b>>() - //~^ ERROR lifetime parameters must be declared prior to type parameters +// can't run rustfix because it doesn't handle multipart suggestions correctly +// compile-flags: -Zborrowck=mir +// we need the above to avoid ast borrowck failure in recovered code + +struct S<'a, T> { + a: &'a T, + b: &'a T, } + +fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { + let _x = (*start..*end) + .map(|x| S { a: start, b: end }) + .collect::<Vec<S<_, 'a>>>(); + //~^ ERROR lifetime parameters must be declared prior to type parameters +} + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.stderr index 1cc82f523c4..2a736491594 100644 --- a/src/test/ui/parser/issue-14303-fncall.stderr +++ b/src/test/ui/parser/issue-14303-fncall.stderr @@ -1,8 +1,12 @@ error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-fncall.rs:4:31 + --> $DIR/issue-14303-fncall.rs:13:29 | -LL | .collect::<Vec<'a, usize, 'b>>() - | ^^ +LL | .collect::<Vec<S<_, 'a>>>(); + | ^^ must be declared prior to type parameters +help: move the lifetime parameter prior to the first type parameter + | +LL | .collect::<Vec<S<'a, _>>>(); + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-path.rs b/src/test/ui/parser/issue-14303-path.rs index f61cb6b8dd6..a08c89f3437 100644 --- a/src/test/ui/parser/issue-14303-path.rs +++ b/src/test/ui/parser/issue-14303-path.rs @@ -1,4 +1,13 @@ -fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {} +mod foo { + pub struct X<'a, 'b, 'c, T> { + a: &'a str, + b: &'b str, + c: &'c str, + t: T, + } +} + +fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} //~^ ERROR lifetime parameters must be declared prior to type parameters fn main() {} diff --git a/src/test/ui/parser/issue-14303-path.stderr b/src/test/ui/parser/issue-14303-path.stderr index 3de8a169c69..fb4fb32e11e 100644 --- a/src/test/ui/parser/issue-14303-path.stderr +++ b/src/test/ui/parser/issue-14303-path.stderr @@ -1,8 +1,14 @@ error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-path.rs:1:37 + --> $DIR/issue-14303-path.rs:10:40 | -LL | fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {} - | ^^ +LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} + | ^^ ^^ must be declared prior to type parameters + | | + | must be declared prior to type parameters +help: move the lifetime parameters prior to the first type parameter + | +LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, 'b, 'c, T>) {} + | ^^^ ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-17383.rs b/src/test/ui/parser/issue-17383.rs index 9c00289287c..04cd43d0b10 100644 --- a/src/test/ui/parser/issue-17383.rs +++ b/src/test/ui/parser/issue-17383.rs @@ -1,8 +1,7 @@ enum X { - A = - b'a' //~ ERROR discriminator values can only be used with a field-less enum - , - B(isize) + A = 3, + //~^ ERROR discriminator values can only be used with a field-less enum + B(usize) } fn main() {} diff --git a/src/test/ui/parser/issue-17383.stderr b/src/test/ui/parser/issue-17383.stderr index b225e11066d..57caa3372a6 100644 --- a/src/test/ui/parser/issue-17383.stderr +++ b/src/test/ui/parser/issue-17383.stderr @@ -1,8 +1,8 @@ error: discriminator values can only be used with a field-less enum - --> $DIR/issue-17383.rs:3:9 + --> $DIR/issue-17383.rs:2:9 | -LL | b'a' //~ ERROR discriminator values can only be used with a field-less enum - | ^^^^ +LL | A = 3, + | ^ only valid in field-less enums error: aborting due to previous error diff --git a/src/test/ui/parser/issue-1802-1.rs b/src/test/ui/parser/issue-1802-1.rs index 050e9a258d1..3c34b0d8feb 100644 --- a/src/test/ui/parser/issue-1802-1.rs +++ b/src/test/ui/parser/issue-1802-1.rs @@ -1,4 +1,7 @@ -// error-pattern:no valid digits found for number +fn log(a: i32, b: i32) {} + fn main() { + let error = 42; log(error, 0b); + //~^ ERROR no valid digits found for number } diff --git a/src/test/ui/parser/issue-1802-1.stderr b/src/test/ui/parser/issue-1802-1.stderr index 5cd6a4f7c68..b7d003df56b 100644 --- a/src/test/ui/parser/issue-1802-1.stderr +++ b/src/test/ui/parser/issue-1802-1.stderr @@ -1,5 +1,5 @@ error: no valid digits found for number - --> $DIR/issue-1802-1.rs:3:16 + --> $DIR/issue-1802-1.rs:5:16 | LL | log(error, 0b); | ^^ diff --git a/src/test/ui/parser/issue-1802-2.rs b/src/test/ui/parser/issue-1802-2.rs index 796db66d22e..3c34b0d8feb 100644 --- a/src/test/ui/parser/issue-1802-2.rs +++ b/src/test/ui/parser/issue-1802-2.rs @@ -1,4 +1,7 @@ -// error-pattern:no valid digits found for number +fn log(a: i32, b: i32) {} + fn main() { - log(error, 0b_usize); + let error = 42; + log(error, 0b); + //~^ ERROR no valid digits found for number } diff --git a/src/test/ui/parser/issue-1802-2.stderr b/src/test/ui/parser/issue-1802-2.stderr index c6c04279666..8491dd07cb7 100644 --- a/src/test/ui/parser/issue-1802-2.stderr +++ b/src/test/ui/parser/issue-1802-2.stderr @@ -1,8 +1,8 @@ error: no valid digits found for number - --> $DIR/issue-1802-2.rs:3:16 + --> $DIR/issue-1802-2.rs:5:16 | -LL | log(error, 0b_usize); - | ^^^ +LL | log(error, 0b); + | ^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-27255.rs b/src/test/ui/parser/issue-27255.rs index c0ff331b8ba..d619688e101 100644 --- a/src/test/ui/parser/issue-27255.rs +++ b/src/test/ui/parser/issue-27255.rs @@ -1,3 +1,10 @@ -impl A .. {} //~ ERROR +trait A {} + +impl A .. {} +//~^ ERROR missing `for` in a trait impl +//~| ERROR `impl Trait for .. {}` is an obsolete syntax + +impl A usize {} +//~^ ERROR missing `for` in a trait impl fn main() {} diff --git a/src/test/ui/parser/issue-27255.stderr b/src/test/ui/parser/issue-27255.stderr index 6d09d82e34f..391a23556c4 100644 --- a/src/test/ui/parser/issue-27255.stderr +++ b/src/test/ui/parser/issue-27255.stderr @@ -1,8 +1,22 @@ error: missing `for` in a trait impl - --> $DIR/issue-27255.rs:1:7 + --> $DIR/issue-27255.rs:3:7 | -LL | impl A .. {} //~ ERROR - | ^ +LL | impl A .. {} + | ^ help: add `for` here -error: aborting due to previous error +error: missing `for` in a trait impl + --> $DIR/issue-27255.rs:7:7 + | +LL | impl A usize {} + | ^^^^^^ help: add `for` here + +error: `impl Trait for .. {}` is an obsolete syntax + --> $DIR/issue-27255.rs:3:1 + | +LL | impl A .. {} + | ^^^^^^^^^^^^ + | + = help: use `auto trait Trait {}` instead + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr index a01517d016d..a889513eaee 100644 --- a/src/test/ui/parser/issue-32214.stderr +++ b/src/test/ui/parser/issue-32214.stderr @@ -2,7 +2,7 @@ error: type parameters must be declared prior to associated type bindings --> $DIR/issue-32214.rs:5:34 | LL | pub fn test<W, I: Trait<Item=(), W> >() {} - | ^ + | ^ must be declared prior to associated type bindings error: aborting due to previous error diff --git a/src/test/ui/parser/lex-bad-numeric-literals.stderr b/src/test/ui/parser/lex-bad-numeric-literals.stderr index b1a91705533..1fa23b8b73c 100644 --- a/src/test/ui/parser/lex-bad-numeric-literals.stderr +++ b/src/test/ui/parser/lex-bad-numeric-literals.stderr @@ -110,7 +110,7 @@ error: octal float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:5:5 | LL | 0o2f32; //~ ERROR: octal float literal is not supported - | ^^^^^^ + | ^^^^^^ not supported error: int literal is too large --> $DIR/lex-bad-numeric-literals.rs:16:5 @@ -128,13 +128,13 @@ error: octal float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:23:5 | LL | 0o123f64; //~ ERROR: octal float literal is not supported - | ^^^^^^^^ + | ^^^^^^^^ not supported error: binary float literal is not supported --> $DIR/lex-bad-numeric-literals.rs:25:5 | LL | 0b101f64; //~ ERROR: binary float literal is not supported - | ^^^^^^^^ + | ^^^^^^^^ not supported error: aborting due to 23 previous errors diff --git a/src/test/ui/parser/no-binary-float-literal.rs b/src/test/ui/parser/no-binary-float-literal.rs index c078bf5f63e..a42d2cbc442 100644 --- a/src/test/ui/parser/no-binary-float-literal.rs +++ b/src/test/ui/parser/no-binary-float-literal.rs @@ -1,7 +1,8 @@ -// error-pattern:binary float literal is not supported - fn main() { 0b101010f64; + //~^ ERROR binary float literal is not supported 0b101.010; + //~^ ERROR binary float literal is not supported 0b101p4f64; + //~^ ERROR invalid suffix `p4f64` for numeric literal } diff --git a/src/test/ui/parser/no-binary-float-literal.stderr b/src/test/ui/parser/no-binary-float-literal.stderr index 7ff3e28ccb6..21f415bcfb0 100644 --- a/src/test/ui/parser/no-binary-float-literal.stderr +++ b/src/test/ui/parser/no-binary-float-literal.stderr @@ -1,8 +1,22 @@ error: binary float literal is not supported - --> $DIR/no-binary-float-literal.rs:5:5 + --> $DIR/no-binary-float-literal.rs:4:5 | LL | 0b101.010; | ^^^^^^^^^ -error: aborting due to previous error +error: binary float literal is not supported + --> $DIR/no-binary-float-literal.rs:2:5 + | +LL | 0b101010f64; + | ^^^^^^^^^^^ not supported + +error: invalid suffix `p4f64` for numeric literal + --> $DIR/no-binary-float-literal.rs:6:5 + | +LL | 0b101p4f64; + | ^^^^^^^^^^ invalid suffix `p4f64` + | + = help: the suffix must be one of the integral types (`u32`, `isize`, etc) + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/no-hex-float-literal.rs b/src/test/ui/parser/no-hex-float-literal.rs index d830c96fc2f..bf11dee0833 100644 --- a/src/test/ui/parser/no-hex-float-literal.rs +++ b/src/test/ui/parser/no-hex-float-literal.rs @@ -1,7 +1,9 @@ -// error-pattern:hexadecimal float literal is not supported - fn main() { 0xABC.Df; + //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields 0x567.89; + //~^ ERROR hexadecimal float literal is not supported 0xDEAD.BEEFp-2f; + //~^ ERROR invalid suffix `f` for float literal + //~| ERROR `{integer}` is a primitive type and therefore doesn't have fields } diff --git a/src/test/ui/parser/no-hex-float-literal.stderr b/src/test/ui/parser/no-hex-float-literal.stderr index 1668cfe5a33..258ab06d5ee 100644 --- a/src/test/ui/parser/no-hex-float-literal.stderr +++ b/src/test/ui/parser/no-hex-float-literal.stderr @@ -1,8 +1,29 @@ error: hexadecimal float literal is not supported - --> $DIR/no-hex-float-literal.rs:5:5 + --> $DIR/no-hex-float-literal.rs:4:5 | LL | 0x567.89; | ^^^^^^^^ -error: aborting due to previous error +error: invalid suffix `f` for float literal + --> $DIR/no-hex-float-literal.rs:6:18 + | +LL | 0xDEAD.BEEFp-2f; + | ^^ invalid suffix `f` + | + = help: valid suffixes are `f32` and `f64` + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/no-hex-float-literal.rs:2:11 + | +LL | 0xABC.Df; + | ^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/no-hex-float-literal.rs:6:12 + | +LL | 0xDEAD.BEEFp-2f; + | ^^^^^ + +error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/parser/no-unsafe-self.stderr b/src/test/ui/parser/no-unsafe-self.stderr index 364c22a9622..84779b09dc7 100644 --- a/src/test/ui/parser/no-unsafe-self.stderr +++ b/src/test/ui/parser/no-unsafe-self.stderr @@ -2,37 +2,37 @@ error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:4:17 | LL | fn foo(*mut self); //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:5:19 | LL | fn baz(*const self); //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:6:13 | LL | fn bar(*self); //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:11:17 | LL | fn foo(*mut self) { } //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:12:19 | LL | fn baz(*const self) { } //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: cannot pass `self` by raw pointer --> $DIR/no-unsafe-self.rs:13:13 | LL | fn bar(*self) { } //~ ERROR cannot pass `self` by raw pointer - | ^^^^ + | ^^^^ cannot pass `self` by raw pointer error: aborting due to 6 previous errors diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs index 108278fa58e..fd25499381a 100644 --- a/src/test/ui/parser/pat-tuple-2.rs +++ b/src/test/ui/parser/pat-tuple-2.rs @@ -1,5 +1,6 @@ fn main() { - match 0 { - (pat, ..,) => {} //~ ERROR trailing comma is not permitted after `..` + match (0, 1, 2) { + (pat, ..,) => {} + //~^ ERROR trailing comma is not permitted after `..` } } diff --git a/src/test/ui/parser/pat-tuple-2.stderr b/src/test/ui/parser/pat-tuple-2.stderr index ec123363566..c3a5c39a8e3 100644 --- a/src/test/ui/parser/pat-tuple-2.stderr +++ b/src/test/ui/parser/pat-tuple-2.stderr @@ -1,8 +1,8 @@ error: trailing comma is not permitted after `..` --> $DIR/pat-tuple-2.rs:3:17 | -LL | (pat, ..,) => {} //~ ERROR trailing comma is not permitted after `..` - | ^ +LL | (pat, ..,) => {} + | ^ trailing comma is not permitted after `..` error: aborting due to previous error diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs index 63dcde45bfb..e1e975d3c3e 100644 --- a/src/test/ui/parser/pat-tuple-3.rs +++ b/src/test/ui/parser/pat-tuple-3.rs @@ -1,5 +1,6 @@ fn main() { - match 0 { - (.., pat, ..) => {} //~ ERROR `..` can only be used once per tuple or tuple struct pattern + match (0, 1, 2) { + (.., pat, ..) => {} + //~^ ERROR `..` can only be used once per tuple or tuple struct pattern } } diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr index 90940eb1723..0ad7d27b94e 100644 --- a/src/test/ui/parser/pat-tuple-3.stderr +++ b/src/test/ui/parser/pat-tuple-3.stderr @@ -1,8 +1,8 @@ error: `..` can only be used once per tuple or tuple struct pattern --> $DIR/pat-tuple-3.rs:3:19 | -LL | (.., pat, ..) => {} //~ ERROR `..` can only be used once per tuple or tuple struct pattern - | ^^ +LL | (.., pat, ..) => {} + | ^^ can only be used once per pattern error: aborting due to previous error diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.rs b/src/test/ui/parser/tag-variant-disr-non-nullary.rs index 35a36cbbf91..83a3b727982 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.rs +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.rs @@ -1,12 +1,11 @@ -//error-pattern: discriminator values can only be used with a field-less enum - -enum color { - red = 0xff0000, - green = 0x00ff00, - blue = 0x0000ff, - black = 0x000000, - white = 0xffffff, - other (str), +enum Color { + Red = 0xff0000, + //~^ ERROR discriminator values can only be used with a field-less enum + Green = 0x00ff00, + Blue = 0x0000ff, + Black = 0x000000, + White = 0xffffff, + Other(usize), } fn main() {} diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr index aa45ea4ac26..cc6312b4545 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr @@ -1,8 +1,17 @@ error: discriminator values can only be used with a field-less enum - --> $DIR/tag-variant-disr-non-nullary.rs:8:13 + --> $DIR/tag-variant-disr-non-nullary.rs:2:11 | -LL | white = 0xffffff, - | ^^^^^^^^ +LL | Red = 0xff0000, + | ^^^^^^^^ only valid in field-less enums +LL | //~^ ERROR discriminator values can only be used with a field-less enum +LL | Green = 0x00ff00, + | ^^^^^^^^ only valid in field-less enums +LL | Blue = 0x0000ff, + | ^^^^^^^^ only valid in field-less enums +LL | Black = 0x000000, + | ^^^^^^^^ only valid in field-less enums +LL | White = 0xffffff, + | ^^^^^^^^ only valid in field-less enums error: aborting due to previous error diff --git a/src/test/ui/parser/where_with_bound.rs b/src/test/ui/parser/where_with_bound.rs index 3a1edb9ffc9..3ca45f1889c 100644 --- a/src/test/ui/parser/where_with_bound.rs +++ b/src/test/ui/parser/where_with_bound.rs @@ -1,4 +1,5 @@ fn foo<T>() where <T>::Item: ToString, T: Iterator { } //~^ ERROR generic parameters on `where` clauses are reserved for future use +//~| ERROR cannot find type `Item` in the crate root fn main() {} diff --git a/src/test/ui/parser/where_with_bound.stderr b/src/test/ui/parser/where_with_bound.stderr index e68f7445558..ff98b3f5fed 100644 --- a/src/test/ui/parser/where_with_bound.stderr +++ b/src/test/ui/parser/where_with_bound.stderr @@ -2,7 +2,14 @@ error: generic parameters on `where` clauses are reserved for future use --> $DIR/where_with_bound.rs:1:19 | LL | fn foo<T>() where <T>::Item: ToString, T: Iterator { } - | ^^^ + | ^^^ currently unsupported -error: aborting due to previous error +error[E0412]: cannot find type `Item` in the crate root + --> $DIR/where_with_bound.rs:1:24 + | +LL | fn foo<T>() where <T>::Item: ToString, T: Iterator { } + | ^^^^ not found in the crate root + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/traits/trait-object-vs-lifetime.rs b/src/test/ui/traits/trait-object-vs-lifetime.rs index 57d9b2df9f5..a12429c868e 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.rs +++ b/src/test/ui/traits/trait-object-vs-lifetime.rs @@ -1,8 +1,6 @@ // A few contrived examples where lifetime should (or should not) be parsed as an object type. // Lifetimes parsed as types are still rejected later by semantic checks. -// compile-flags: -Z continue-parse-after-error - struct S<'a, T>(&'a u8, T); fn main() { diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr index 20218c19e45..4cc96bae5cd 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr @@ -1,29 +1,33 @@ error: lifetime parameters must be declared prior to type parameters - --> $DIR/trait-object-vs-lifetime.rs:16:25 + --> $DIR/trait-object-vs-lifetime.rs:14:25 | LL | let _: S<'static +, 'static>; - | ^^^^^^^ + | ^^^^^^^ must be declared prior to type parameters +help: move the lifetime parameter prior to the first type parameter + | +LL | let _: S<'static, 'static +>; + | ^^^^^^^^ -- error[E0224]: at least one non-builtin trait is required for an object type - --> $DIR/trait-object-vs-lifetime.rs:11:23 + --> $DIR/trait-object-vs-lifetime.rs:9:23 | LL | let _: S<'static, 'static +>; | ^^^^^^^^^ error[E0107]: wrong number of lifetime arguments: expected 1, found 2 - --> $DIR/trait-object-vs-lifetime.rs:13:23 + --> $DIR/trait-object-vs-lifetime.rs:11:23 | LL | let _: S<'static, 'static>; | ^^^^^^^ unexpected lifetime argument error[E0107]: wrong number of type arguments: expected 1, found 0 - --> $DIR/trait-object-vs-lifetime.rs:13:12 + --> $DIR/trait-object-vs-lifetime.rs:11:12 | LL | let _: S<'static, 'static>; | ^^^^^^^^^^^^^^^^^^^ expected 1 type argument error[E0224]: at least one non-builtin trait is required for an object type - --> $DIR/trait-object-vs-lifetime.rs:16:14 + --> $DIR/trait-object-vs-lifetime.rs:14:14 | LL | let _: S<'static +, 'static>; | ^^^^^^^^^ |
