diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a4d2c5b6110..7842d9dca53 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -394,6 +394,17 @@ impl<'a> Parser<'a> { Parser::token_to_string(&self.token) } + pub fn this_token_descr(&self) -> String { + let s = self.this_token_to_string(); + if self.token.is_strict_keyword() { + format!("keyword `{}`", s) + } else if self.token.is_reserved_keyword() { + format!("reserved keyword `{}`", s) + } else { + format!("`{}`", s) + } + } + pub fn unexpected_last(&self, t: &token::Token) -> PResult<'a, T> { let token_str = Parser::token_to_string(t); let last_span = self.last_span; @@ -1466,7 +1477,7 @@ impl<'a> Parser<'a> { self.parse_qualified_path(PathStyle::Type)?; TyKind::Path(Some(qself), path) - } else if self.is_path_start() { + } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Type)?; if self.check(&token::Not) { // MACRO INVOCATION @@ -1485,9 +1496,8 @@ impl<'a> Parser<'a> { // TYPE TO BE INFERRED TyKind::Infer } else { - let this_token_str = self.this_token_to_string(); - let msg = format!("expected type, found `{}`", this_token_str); - return Err(self.fatal(&msg[..])); + let msg = format!("expected type, found {}", self.this_token_descr()); + return Err(self.fatal(&msg)); }; let sp = mk_sp(lo, self.last_span.hi); @@ -1604,12 +1614,12 @@ impl<'a> Parser<'a> { } /// Matches token_lit = LIT_INTEGER | ... - pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, LitKind> { - match *tok { + pub fn parse_lit_token(&mut self) -> PResult<'a, LitKind> { + let out = match self.token { token::Interpolated(token::NtExpr(ref v)) => { match v.node { - ExprKind::Lit(ref lit) => { Ok(lit.node.clone()) } - _ => { return self.unexpected_last(tok); } + ExprKind::Lit(ref lit) => { lit.node.clone() } + _ => { return self.unexpected_last(&self.token); } } } token::Literal(lit, suf) => { @@ -1624,13 +1634,13 @@ impl<'a> Parser<'a> { (false, parse::integer_lit(&s.as_str(), suf.as_ref().map(|s| s.as_str()), &self.sess.span_diagnostic, - self.last_span)) + self.span)) } token::Float(s) => { (false, parse::float_lit(&s.as_str(), suf.as_ref().map(|s| s.as_str()), &self.sess.span_diagnostic, - self.last_span)) + self.span)) } token::Str_(s) => { @@ -1652,14 +1662,17 @@ impl<'a> Parser<'a> { }; if suffix_illegal { - let sp = self.last_span; + let sp = self.span; self.expect_no_suffix(sp, &format!("{} literal", lit.short_name()), suf) } - Ok(out) + out } - _ => { return self.unexpected_last(tok); } - } + _ => { return self.unexpected_last(&self.token); } + }; + + self.bump(); + Ok(out) } /// Matches lit = true | false | token_lit @@ -1670,8 +1683,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(keywords::False) { LitKind::Bool(false) } else { - let token = self.bump_and_get(); - let lit = self.lit_from_token(&token)?; + let lit = self.parse_lit_token()?; lit }; Ok(codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }) @@ -2338,7 +2350,7 @@ impl<'a> Parser<'a> { let mut db = self.fatal("expected expression, found statement (`let`)"); db.note("variable declaration using `let` is a statement"); return Err(db); - } else if self.is_path_start() { + } else if self.token.is_path_start() { let pth = self.parse_path(PathStyle::Expr)?; // `!`, as an operator, is prefix, so we know this isn't that @@ -2419,10 +2431,18 @@ impl<'a> Parser<'a> { hi = pth.span.hi; ex = ExprKind::Path(None, pth); } else { - // other literal expression - let lit = self.parse_lit()?; - hi = lit.span.hi; - ex = ExprKind::Lit(P(lit)); + match self.parse_lit() { + Ok(lit) => { + hi = lit.span.hi; + ex = ExprKind::Lit(P(lit)); + } + Err(mut err) => { + err.cancel(); + let msg = format!("expected expression, found {}", + self.this_token_descr()); + return Err(self.fatal(&msg)); + } + } } } } @@ -3567,7 +3587,7 @@ impl<'a> Parser<'a> { } fn parse_pat_range_end(&mut self) -> PResult<'a, P> { - if self.is_path_start() { + if self.token.is_path_start() { let lo = self.span.lo; let (qself, path) = if self.eat_lt() { // Parse a qualified path @@ -3585,12 +3605,6 @@ impl<'a> Parser<'a> { } } - fn is_path_start(&self) -> bool { - (self.token == token::Lt || self.token == token::ModSep - || self.token.is_ident() || self.token.is_path()) - && !self.token.is_keyword(keywords::True) && !self.token.is_keyword(keywords::False) - } - /// Parse a pattern. pub fn parse_pat(&mut self) -> PResult<'a, P> { maybe_whole!(self, NtPat); @@ -3641,7 +3655,7 @@ impl<'a> Parser<'a> { // Parse box pat let subpat = self.parse_pat()?; pat = PatKind::Box(subpat); - } else if self.is_path_start() { + } else if self.token.is_path_start() { // Parse pattern starting with a path if self.token.is_ident() && self.look_ahead(1, |t| *t != token::DotDotDot && *t != token::OpenDelim(token::Brace) && @@ -3731,12 +3745,20 @@ impl<'a> Parser<'a> { } } else { // Try to parse everything else as literal with optional minus - let begin = self.parse_pat_literal_maybe_minus()?; - if self.eat(&token::DotDotDot) { - let end = self.parse_pat_range_end()?; - pat = PatKind::Range(begin, end); - } else { - pat = PatKind::Lit(begin); + match self.parse_pat_literal_maybe_minus() { + Ok(begin) => { + if self.eat(&token::DotDotDot) { + let end = self.parse_pat_range_end()?; + pat = PatKind::Range(begin, end); + } else { + pat = PatKind::Lit(begin); + } + } + Err(mut err) => { + err.cancel(); + let msg = format!("expected pattern, found {}", self.this_token_descr()); + return Err(self.fatal(&msg)); + } } } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 32078c875be..fcb6c3539db 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -243,6 +243,11 @@ impl Token { self.is_keyword(keywords::Const) } + pub fn is_path_start(&self) -> bool { + self == &ModSep || self == &Lt || self.is_path() || + self.is_path_segment_keyword() || self.is_ident() && !self.is_any_keyword() + } + /// Maps a token to its corresponding binary operator. pub fn to_binop(&self) -> Option { match *self { diff --git a/src/test/compile-fail/fail-simple.rs b/src/test/compile-fail/fail-simple.rs index 97b709592a9..e889d354770 100644 --- a/src/test/compile-fail/fail-simple.rs +++ b/src/test/compile-fail/fail-simple.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -// error-pattern:unexpected token fn main() { - panic!(@); + panic!(@); //~ ERROR expected expression, found `@` } diff --git a/src/test/compile-fail/issue-10636-2.rs b/src/test/compile-fail/issue-10636-2.rs index 747252d5924..beaf9e5059f 100644 --- a/src/test/compile-fail/issue-10636-2.rs +++ b/src/test/compile-fail/issue-10636-2.rs @@ -15,4 +15,4 @@ pub fn trace_option(option: Option) { option.map(|some| 42; //~ NOTE: unclosed delimiter //~^ ERROR: expected one of } //~ ERROR: incorrect close delimiter -//~^ ERROR: unexpected token +//~^ ERROR: expected expression, found `)` diff --git a/src/test/compile-fail/issue-31804.rs b/src/test/compile-fail/issue-31804.rs index b6a04bee85d..cea52b11c5d 100644 --- a/src/test/compile-fail/issue-31804.rs +++ b/src/test/compile-fail/issue-31804.rs @@ -13,4 +13,4 @@ fn main() { let -} //~ ERROR unexpected token: `}` +} //~ ERROR expected pattern, found `}` diff --git a/src/test/compile-fail/macro-context.rs b/src/test/compile-fail/macro-context.rs index 8fa5e0a7089..5d07f0747ff 100644 --- a/src/test/compile-fail/macro-context.rs +++ b/src/test/compile-fail/macro-context.rs @@ -12,7 +12,7 @@ // (typeof used because it's surprisingly hard to find an unparsed token after a stmt) macro_rules! m { - () => ( i ; typeof ); //~ ERROR `typeof` is a reserved keyword + () => ( i ; typeof ); //~ ERROR expected expression, found reserved keyword `typeof` //~| ERROR macro expansion ignores token `typeof` //~| ERROR macro expansion ignores token `;` //~| ERROR macro expansion ignores token `;` diff --git a/src/test/compile-fail/macro-incomplete-parse.rs b/src/test/compile-fail/macro-incomplete-parse.rs index 0d5f9079649..8d515622e53 100644 --- a/src/test/compile-fail/macro-incomplete-parse.rs +++ b/src/test/compile-fail/macro-incomplete-parse.rs @@ -19,7 +19,7 @@ macro_rules! ignored_item { } macro_rules! ignored_expr { - () => ( 1, //~ ERROR unexpected token: `,` + () => ( 1, //~ ERROR expected expression, found `,` 2 ) } diff --git a/src/test/compile-fail/reserved-become.rs b/src/test/compile-fail/reserved-become.rs index 82e9ebc10d1..bcda61e363d 100644 --- a/src/test/compile-fail/reserved-become.rs +++ b/src/test/compile-fail/reserved-become.rs @@ -10,5 +10,5 @@ fn main() { let become = 0; - //~^ ERROR `become` is a reserved keyword + //~^ ERROR expected pattern, found reserved keyword `become` } diff --git a/src/test/compile-fail/token-error-correct.rs b/src/test/compile-fail/token-error-correct.rs index 6c54acd7bdb..f5fecf3e174 100644 --- a/src/test/compile-fail/token-error-correct.rs +++ b/src/test/compile-fail/token-error-correct.rs @@ -13,8 +13,10 @@ fn main() { foo(bar(; //~ NOTE: unclosed delimiter //~^ NOTE: unclosed delimiter - //~^^ ERROR: unexpected token: `;` + //~^^ ERROR: expected expression, found `;` //~^^^ ERROR: unresolved name `bar` //~^^^^ ERROR: unresolved name `foo` + //~^^^^^ ERROR: expected one of `)`, `,`, `.`, `<`, `?` } //~ ERROR: incorrect close delimiter: `}` //~^ ERROR: incorrect close delimiter: `}` +//~^^ ERROR: expected expression, found `)` diff --git a/src/test/compile-fail/vec-macro-with-comma-only.rs b/src/test/compile-fail/vec-macro-with-comma-only.rs index 8c8e789cd96..346cf1ec555 100644 --- a/src/test/compile-fail/vec-macro-with-comma-only.rs +++ b/src/test/compile-fail/vec-macro-with-comma-only.rs @@ -9,5 +9,5 @@ // except according to those terms. pub fn main() { - vec!(,); //~ ERROR unexpected token + vec!(,); //~ ERROR expected expression, found `,` } diff --git a/src/test/parse-fail/issue-14303-path.rs b/src/test/parse-fail/issue-14303-path.rs index 7c30b5f2629..431a917c2d9 100644 --- a/src/test/parse-fail/issue-14303-path.rs +++ b/src/test/parse-fail/issue-14303-path.rs @@ -12,4 +12,4 @@ fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {} //~^ ERROR lifetime parameters must be declared prior to type parameters -//~^^ ERROR unexpected token +//~^^ ERROR expected pattern, found `'c` diff --git a/src/test/parse-fail/issue-32505.rs b/src/test/parse-fail/issue-32505.rs index e697e98bc06..246941ff259 100644 --- a/src/test/parse-fail/issue-32505.rs +++ b/src/test/parse-fail/issue-32505.rs @@ -11,7 +11,7 @@ // compile-flags: -Z parse-only -Z continue-parse-after-error pub fn test() { - foo(|_|) //~ ERROR unexpected token: `)` + foo(|_|) //~ ERROR expected expression, found `)` } fn main() { } diff --git a/src/test/parse-fail/keyword-abstract.rs b/src/test/parse-fail/keyword-abstract.rs index bd3fbbe79a8..2db5a5c583a 100644 --- a/src/test/parse-fail/keyword-abstract.rs +++ b/src/test/parse-fail/keyword-abstract.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only fn main() { - let abstract = (); //~ ERROR `abstract` is a reserved keyword + let abstract = (); //~ ERROR expected pattern, found reserved keyword `abstract` } diff --git a/src/test/parse-fail/keyword-final.rs b/src/test/parse-fail/keyword-final.rs index 4b06312d099..be29a739443 100644 --- a/src/test/parse-fail/keyword-final.rs +++ b/src/test/parse-fail/keyword-final.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only fn main() { - let final = (); //~ ERROR `final` is a reserved keyword + let final = (); //~ ERROR expected pattern, found reserved keyword `final` } diff --git a/src/test/parse-fail/keyword-override.rs b/src/test/parse-fail/keyword-override.rs index 3f79e437189..60333762b33 100644 --- a/src/test/parse-fail/keyword-override.rs +++ b/src/test/parse-fail/keyword-override.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only fn main() { - let override = (); //~ ERROR `override` is a reserved keyword + let override = (); //~ ERROR expected pattern, found reserved keyword `override` } diff --git a/src/test/parse-fail/keyword-typeof.rs b/src/test/parse-fail/keyword-typeof.rs index 29ec4f5844b..40e26bd375a 100644 --- a/src/test/parse-fail/keyword-typeof.rs +++ b/src/test/parse-fail/keyword-typeof.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only fn main() { - let typeof = (); //~ ERROR `typeof` is a reserved keyword + let typeof = (); //~ ERROR expected pattern, found reserved keyword `typeof` } diff --git a/src/test/parse-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs index 5e27d3e4f38..bb8a1dfdb19 100644 --- a/src/test/parse-fail/keywords-followed-by-double-colon.rs +++ b/src/test/parse-fail/keywords-followed-by-double-colon.rs @@ -12,5 +12,5 @@ fn main() { struct::foo(); //~ ERROR expected identifier - mut::baz(); //~ ERROR expected identifier + mut::baz(); //~ ERROR expected expression, found keyword `mut` } diff --git a/src/test/parse-fail/match-arrows-block-then-binop.rs b/src/test/parse-fail/match-arrows-block-then-binop.rs index 3026e159a44..e8cfb77f059 100644 --- a/src/test/parse-fail/match-arrows-block-then-binop.rs +++ b/src/test/parse-fail/match-arrows-block-then-binop.rs @@ -14,6 +14,6 @@ fn main() { match 0 { 0 => { - } + 5 //~ ERROR unexpected token: `+` + } + 5 //~ ERROR expected pattern, found `+` } } diff --git a/src/test/parse-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs index 1ef8cd2714d..648c46d246c 100644 --- a/src/test/parse-fail/obsolete-proc.rs +++ b/src/test/parse-fail/obsolete-proc.rs @@ -12,9 +12,8 @@ // Test that we generate obsolete syntax errors around usages of `proc`. -fn foo(p: proc()) { } //~ ERROR `proc` is a reserved keyword +fn foo(p: proc()) { } //~ ERROR expected type, found reserved keyword `proc` -fn bar() { proc() 1; } //~ ERROR `proc` is a reserved keyword - //~^ ERROR expected +fn bar() { proc() 1; } //~ ERROR expected expression, found reserved keyword `proc` fn main() { } diff --git a/src/test/parse-fail/removed-syntax-mode.rs b/src/test/parse-fail/removed-syntax-mode.rs index 4dafc36e912..6e99f8b3eea 100644 --- a/src/test/parse-fail/removed-syntax-mode.rs +++ b/src/test/parse-fail/removed-syntax-mode.rs @@ -10,4 +10,4 @@ // compile-flags: -Z parse-only -fn f(+x: isize) {} //~ ERROR unexpected token: `+` +fn f(+x: isize) {} //~ ERROR expected pattern, found `+` diff --git a/src/test/parse-fail/removed-syntax-mut-vec-expr.rs b/src/test/parse-fail/removed-syntax-mut-vec-expr.rs index 301bd0e8b1c..7e5bd27b497 100644 --- a/src/test/parse-fail/removed-syntax-mut-vec-expr.rs +++ b/src/test/parse-fail/removed-syntax-mut-vec-expr.rs @@ -11,7 +11,5 @@ // compile-flags: -Z parse-only fn f() { - let v = [mut 1, 2, 3, 4]; - //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `!`, `,`, `.`, `::`, `;`, `?`, `]`, `{`, or an operator, found `1` + let v = [mut 1, 2, 3, 4]; //~ ERROR expected expression, found keyword `mut` } diff --git a/src/test/parse-fail/removed-syntax-mut-vec-ty.rs b/src/test/parse-fail/removed-syntax-mut-vec-ty.rs index 91918f01bb0..0cdf1981a23 100644 --- a/src/test/parse-fail/removed-syntax-mut-vec-ty.rs +++ b/src/test/parse-fail/removed-syntax-mut-vec-ty.rs @@ -10,6 +10,4 @@ // compile-flags: -Z parse-only -type v = [mut isize]; - //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `isize` +type v = [mut isize]; //~ ERROR expected type, found keyword `mut` diff --git a/src/test/parse-fail/removed-syntax-uniq-mut-expr.rs b/src/test/parse-fail/removed-syntax-uniq-mut-expr.rs index 2f637cf0b4e..b16c77ab6b5 100644 --- a/src/test/parse-fail/removed-syntax-uniq-mut-expr.rs +++ b/src/test/parse-fail/removed-syntax-uniq-mut-expr.rs @@ -11,7 +11,5 @@ // compile-flags: -Z parse-only fn f() { - let a_box = box mut 42; - //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `42` + let a_box = box mut 42; //~ ERROR expected expression, found keyword `mut` } diff --git a/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs b/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs index e1637901266..9bd8dc9b11b 100644 --- a/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs +++ b/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs @@ -10,6 +10,4 @@ // compile-flags: -Z parse-only -type mut_box = Box; - //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `isize` +type mut_box = Box; //~ ERROR expected type, found keyword `mut` diff --git a/src/test/parse-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs index a4a4c0dcfd9..f3af8740be9 100644 --- a/src/test/parse-fail/unsized2.rs +++ b/src/test/parse-fail/unsized2.rs @@ -15,8 +15,5 @@ fn f() {} pub fn main() { - f(); - //~^ ERROR expected identifier, found keyword `type` - //~^^ ERROR: chained comparison - //~^^^ HELP: use `::< + f(); //~ ERROR expected expression, found keyword `type` }