diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dd4c2393fa5..c27a1f79d8c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -46,7 +46,7 @@ use crate::ThinVec; use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use crate::symbol::{Symbol, keywords}; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{Span, MultiSpan, BytePos, FileName}; use log::{debug, trace}; @@ -256,6 +256,7 @@ pub struct Parser<'a> { /// it gets removed from here. Every entry left at the end gets emitted as an independent /// error. crate unclosed_delims: Vec, + last_unexpected_token_span: Option, } @@ -582,6 +583,7 @@ impl<'a> Parser<'a> { unmatched_angle_bracket_count: 0, max_angle_bracket_count: 0, unclosed_delims: Vec::new(), + last_unexpected_token_span: None, }; let tok = parser.next_tok(); @@ -775,6 +777,8 @@ impl<'a> Parser<'a> { } else if inedible.contains(&self.token) { // leave it in the input Ok(false) + } else if self.last_unexpected_token_span == Some(self.span) { + FatalError.raise(); } else { let mut expected = edible.iter() .map(|x| TokenType::Token(x.clone())) @@ -802,6 +806,7 @@ impl<'a> Parser<'a> { (self.sess.source_map().next_point(self.prev_span), format!("expected {} here", expect))) }; + self.last_unexpected_token_span = Some(self.span); let mut err = self.fatal(&msg_exp); if self.token.is_ident_named("and") { err.span_suggestion_short( @@ -6332,10 +6337,11 @@ impl<'a> Parser<'a> { &token::CloseDelim(token::Paren), sep, parse_arg_fn)?; fn_inputs.append(&mut input); (fn_inputs, recovered) - } else if let Err(err) = self.expect_one_of(&[], &[]) { - return Err(err); } else { - (vec![self_arg], true) + match self.expect_one_of(&[], &[]) { + Err(err) => return Err(err), + Ok(recovered) => (vec![self_arg], recovered), + } } } else { self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)? diff --git a/src/test/ui/issues/issue-58856-1.rs b/src/test/ui/issues/issue-58856-1.rs index 9311bb0802f..f5edac0d2e3 100644 --- a/src/test/ui/issues/issue-58856-1.rs +++ b/src/test/ui/issues/issue-58856-1.rs @@ -1,9 +1,8 @@ +struct A; + impl A { -//~^ ERROR cannot find type `A` in this scope - fn b(self> + fn b(self> {} //~^ ERROR expected one of `)`, `,`, or `:`, found `>` - //~| ERROR expected one of `->`, `where`, or `{`, found `>` - //~| ERROR expected one of `->`, `async`, `const`, `crate`, `default`, `existential`, } fn main() {} diff --git a/src/test/ui/issues/issue-58856-1.stderr b/src/test/ui/issues/issue-58856-1.stderr index 3cbfd375e78..85101e467b1 100644 --- a/src/test/ui/issues/issue-58856-1.stderr +++ b/src/test/ui/issues/issue-58856-1.stderr @@ -1,30 +1,11 @@ error: expected one of `)`, `,`, or `:`, found `>` - --> $DIR/issue-58856-1.rs:3:14 + --> $DIR/issue-58856-1.rs:4:14 | -LL | fn b(self> +LL | fn b(self> {} | - ^ | | | | | help: `)` may belong here | unclosed delimiter -error: expected one of `->`, `where`, or `{`, found `>` - --> $DIR/issue-58856-1.rs:3:14 - | -LL | fn b(self> - | ^ expected one of `->`, `where`, or `{` here +error: aborting due to previous error -error: expected one of `->`, `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, `where`, or `}`, found `>` - --> $DIR/issue-58856-1.rs:3:14 - | -LL | fn b(self> - | ^ expected one of 13 possible tokens here - -error[E0412]: cannot find type `A` in this scope - --> $DIR/issue-58856-1.rs:1:6 - | -LL | impl A { - | ^ not found in this scope - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/issues/issue-58856-2.rs b/src/test/ui/issues/issue-58856-2.rs index 4c764761e8e..acc38e4c201 100644 --- a/src/test/ui/issues/issue-58856-2.rs +++ b/src/test/ui/issues/issue-58856-2.rs @@ -1,11 +1,12 @@ +struct Empty; + trait Howness {} + impl Howness for () { fn how_are_you(&self -> Empty { //~^ ERROR expected one of `)` or `,`, found `->` //~| ERROR method `how_are_you` is not a member of trait `Howness` - //~| ERROR cannot find type `Empty` in this scope Empty - //~^ ERROR cannot find value `Empty` in this scope } } //~^ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, diff --git a/src/test/ui/issues/issue-58856-2.stderr b/src/test/ui/issues/issue-58856-2.stderr index 30027278e23..55a9e9d5cb8 100644 --- a/src/test/ui/issues/issue-58856-2.stderr +++ b/src/test/ui/issues/issue-58856-2.stderr @@ -1,5 +1,5 @@ error: expected one of `)` or `,`, found `->` - --> $DIR/issue-58856-2.rs:3:26 + --> $DIR/issue-58856-2.rs:6:26 | LL | fn how_are_you(&self -> Empty { | - -^^ @@ -8,7 +8,7 @@ LL | fn how_are_you(&self -> Empty { | unclosed delimiter error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `)` - --> $DIR/issue-58856-2.rs:10:1 + --> $DIR/issue-58856-2.rs:11:1 | LL | } | - expected one of 11 possible tokens here @@ -16,40 +16,15 @@ LL | } | ^ unexpected token error[E0407]: method `how_are_you` is not a member of trait `Howness` - --> $DIR/issue-58856-2.rs:3:5 + --> $DIR/issue-58856-2.rs:6:5 | LL | / fn how_are_you(&self -> Empty { LL | | //~^ ERROR expected one of `)` or `,`, found `->` LL | | //~| ERROR method `how_are_you` is not a member of trait `Howness` -LL | | //~| ERROR cannot find type `Empty` in this scope LL | | Empty -LL | | //~^ ERROR cannot find value `Empty` in this scope LL | | } | |_____^ not a member of trait `Howness` -error[E0412]: cannot find type `Empty` in this scope - --> $DIR/issue-58856-2.rs:3:29 - | -LL | fn how_are_you(&self -> Empty { - | ^^^^^ not found in this scope -help: possible candidates are found in other modules, you can import them into scope - | -LL | use std::io::Empty; - | -LL | use std::iter::Empty; - | +error: aborting due to 3 previous errors -error[E0425]: cannot find value `Empty` in this scope - --> $DIR/issue-58856-2.rs:7:9 - | -LL | Empty - | ^^^^^ not found in this scope -help: possible candidate is found in another module, you can import it into scope - | -LL | use std::sync::mpsc::TryRecvError::Empty; - | - -error: aborting due to 5 previous errors - -Some errors occurred: E0407, E0412, E0425. -For more information about an error, try `rustc --explain E0407`. +For more information about this error, try `rustc --explain E0407`. diff --git a/src/test/ui/parser/recover-enum2.rs b/src/test/ui/parser/recover-enum2.rs index 65a18773787..7f2f2cc7ab0 100644 --- a/src/test/ui/parser/recover-enum2.rs +++ b/src/test/ui/parser/recover-enum2.rs @@ -25,9 +25,6 @@ fn main() { // fail again enum Test4 { Nope(i32 {}) //~ ERROR: found `{` - //~^ ERROR: found `{` } } - // still recover later - let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_` } diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr index b308e644ad9..315bfde77c7 100644 --- a/src/test/ui/parser/recover-enum2.stderr +++ b/src/test/ui/parser/recover-enum2.stderr @@ -10,17 +10,5 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{` LL | Nope(i32 {}) //~ ERROR: found `{` | ^ expected one of 7 possible tokens here -error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `...`, `::`, `<`, `?`, `[`, `_`, `crate`, `dyn`, `extern`, `fn`, `for`, `impl`, `pub`, `unsafe`, `}`, or lifetime, found `{` - --> $DIR/recover-enum2.rs:27:22 - | -LL | Nope(i32 {}) //~ ERROR: found `{` - | ^ expected one of 24 possible tokens here - -error: expected expression, found reserved identifier `_` - --> $DIR/recover-enum2.rs:32:22 - | -LL | let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_` - | ^ expected expression - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors