From adb96ec64b8d5e8cff191315668a5bfe0480909c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Oct 2018 11:54:31 -0700 Subject: [PATCH] Provide specific label for patern parsing error --- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/quote.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 2 +- src/libsyntax/parse/parser.rs | 42 +++++++++++-------- src/libsyntax/util/parser_testing.rs | 2 +- src/test/ui/parser/issue-33413.rs | 3 +- src/test/ui/parser/issue-33413.stderr | 9 ++-- src/test/ui/parser/lifetime-in-pattern.stderr | 5 +-- src/test/ui/parser/removed-syntax-mode.rs | 3 +- src/test/ui/parser/removed-syntax-mode.stderr | 9 ++-- .../ui/self/self-vs-path-ambiguity.stderr | 5 +-- 11 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 33b651e1b38..84e40a7e403 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1030,7 +1030,7 @@ pub fn parse_ast_fragment(&mut self, kind: AstFragmentKind, macro_legacy_warning } }, AstFragmentKind::Ty => AstFragment::Ty(self.parse_ty()?), - AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat()?), + AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat(None)?), }) } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 62bc9fae3b5..37800a334c6 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -419,7 +419,7 @@ pub fn parse_item_panic(parser: &mut Parser) -> Option> { } pub fn parse_pat_panic(parser: &mut Parser) -> P { - panictry!(parser.parse_pat()) + panictry!(parser.parse_pat(None)) } pub fn parse_arm_panic(parser: &mut Parser) -> Arm { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 03a8376e763..d6c95a3d7c8 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -881,7 +881,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { FatalError.raise(); } }, - "pat" => token::NtPat(panictry!(p.parse_pat())), + "pat" => token::NtPat(panictry!(p.parse_pat(None))), "expr" => token::NtExpr(panictry!(p.parse_expr())), "literal" => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())), "ty" => token::NtTy(panictry!(p.parse_ty())), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5ab0d8166b0..d700e6066cb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1827,10 +1827,7 @@ fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { debug!("parse_arg_general parse_pat (require_name:{})", require_name); self.eat_incorrect_doc_comment("method arguments"); - let pat = self.parse_pat().map_err(|mut err| { - err.span_label(self.span, "expected argument name"); - err - })?; + let pat = self.parse_pat(Some("argument name"))?; if let Err(mut err) = self.expect(&token::Colon) { // If we find a pattern followed by an identifier, it could be an (incorrect) @@ -1879,7 +1876,7 @@ fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { // Recover from attempting to parse the argument as a type without pattern. err.cancel(); mem::replace(self, parser_snapshot_before_ty); - let pat = self.parse_pat()?; + let pat = self.parse_pat(Some("argument name"))?; self.expect(&token::Colon)?; let ty = self.parse_ty()?; @@ -1917,7 +1914,7 @@ fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { /// Parse an argument in a lambda header e.g. |arg, arg| fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> { - let pat = self.parse_pat()?; + let pat = self.parse_pat(Some("argument name"))?; let t = if self.eat(&token::Colon) { self.parse_ty()? } else { @@ -3784,7 +3781,7 @@ fn parse_pat_list(&mut self) -> PResult<'a, (Vec>, Option, bool)> "`..` can only be used once per tuple or tuple struct pattern"); } } else if !self.check(&token::CloseDelim(token::Paren)) { - fields.push(self.parse_pat()?); + fields.push(self.parse_pat(None)?); } else { break } @@ -3840,7 +3837,7 @@ fn parse_pat_vec_elements( } } - let subpat = self.parse_pat()?; + let subpat = self.parse_pat(None)?; if before_slice && self.eat(&token::DotDot) { slice = Some(subpat); before_slice = false; @@ -3865,7 +3862,7 @@ fn parse_pat_field( // Parsing a pattern of the form "fieldname: pat" let fieldname = self.parse_field_name()?; self.bump(); - let pat = self.parse_pat()?; + let pat = self.parse_pat(None)?; hi = pat.span; (pat, fieldname, false) } else { @@ -4067,7 +4064,7 @@ fn parse_as_ident(&mut self) -> bool { /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast /// to subpatterns within such). fn parse_top_level_pat(&mut self) -> PResult<'a, P> { - let pat = self.parse_pat()?; + let pat = self.parse_pat(None)?; if self.token == token::Comma { // An unexpected comma after a top-level pattern is a clue that the // user (perhaps more accustomed to some other language) forgot the @@ -4099,13 +4096,17 @@ fn parse_top_level_pat(&mut self) -> PResult<'a, P> { } /// Parse a pattern. - pub fn parse_pat(&mut self) -> PResult<'a, P> { - self.parse_pat_with_range_pat(true) + pub fn parse_pat(&mut self, expected: Option<&'static str>) -> PResult<'a, P> { + self.parse_pat_with_range_pat(true, expected) } /// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are /// allowed. - fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P> { + fn parse_pat_with_range_pat( + &mut self, + allow_range_pat: bool, + expected: Option<&'static str>, + ) -> PResult<'a, P> { maybe_whole!(self, NtPat, |x| x); let lo = self.span; @@ -4121,7 +4122,7 @@ fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P

{ @@ -4167,7 +4168,7 @@ fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P

PResult<'a, P

{ self.cancel(&mut err); - let msg = format!("expected pattern, found {}", self.this_token_descr()); + let expected = expected.unwrap_or("pattern"); + let msg = format!( + "expected {}, found {}", + expected, + self.this_token_descr(), + ); let mut err = self.fatal(&msg); - err.span_label(self.span, "expected pattern"); + err.span_label(self.span, format!("expected {}", expected)); return Err(err); } } @@ -4313,7 +4319,7 @@ fn parse_pat_ident(&mut self, -> PResult<'a, PatKind> { let ident = self.parse_ident()?; let sub = if self.eat(&token::At) { - Some(self.parse_pat()?) + Some(self.parse_pat(Some("binding pattern"))?) } else { None }; diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 374154e6333..98e9272e6d8 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -68,7 +68,7 @@ pub fn string_to_item (source_str : String) -> Option> { pub fn string_to_pat(source_str: String) -> P { let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { - p.parse_pat() + p.parse_pat(None) }) } diff --git a/src/test/ui/parser/issue-33413.rs b/src/test/ui/parser/issue-33413.rs index 25ae7b4c55a..7c3b84a5185 100644 --- a/src/test/ui/parser/issue-33413.rs +++ b/src/test/ui/parser/issue-33413.rs @@ -11,5 +11,6 @@ // compile-flags: -Z parse-only impl S { - fn f(*, a: u8) -> u8 {} //~ ERROR expected pattern, found `*` + fn f(*, a: u8) -> u8 {} + //~^ ERROR expected argument name, found `*` } diff --git a/src/test/ui/parser/issue-33413.stderr b/src/test/ui/parser/issue-33413.stderr index 4cdd14a3e27..e0d69e596f2 100644 --- a/src/test/ui/parser/issue-33413.stderr +++ b/src/test/ui/parser/issue-33413.stderr @@ -1,11 +1,8 @@ -error: expected pattern, found `*` +error: expected argument name, found `*` --> $DIR/issue-33413.rs:14:10 | -LL | fn f(*, a: u8) -> u8 {} //~ ERROR expected pattern, found `*` - | ^ - | | - | expected pattern - | expected argument name +LL | fn f(*, a: u8) -> u8 {} + | ^ expected argument name error: aborting due to previous error diff --git a/src/test/ui/parser/lifetime-in-pattern.stderr b/src/test/ui/parser/lifetime-in-pattern.stderr index 83ca1b0ba26..86cc3c5b0cb 100644 --- a/src/test/ui/parser/lifetime-in-pattern.stderr +++ b/src/test/ui/parser/lifetime-in-pattern.stderr @@ -2,10 +2,7 @@ error: unexpected lifetime `'a` in pattern --> $DIR/lifetime-in-pattern.rs:13:10 | LL | fn test(&'a str) { - | ^^ - | | - | unexpected lifetime - | expected argument name + | ^^ unexpected lifetime error: aborting due to previous error diff --git a/src/test/ui/parser/removed-syntax-mode.rs b/src/test/ui/parser/removed-syntax-mode.rs index 6e99f8b3eea..c2f87d8afce 100644 --- a/src/test/ui/parser/removed-syntax-mode.rs +++ b/src/test/ui/parser/removed-syntax-mode.rs @@ -10,4 +10,5 @@ // compile-flags: -Z parse-only -fn f(+x: isize) {} //~ ERROR expected pattern, found `+` +fn f(+x: isize) {} +//~^ ERROR expected argument name, found `+` diff --git a/src/test/ui/parser/removed-syntax-mode.stderr b/src/test/ui/parser/removed-syntax-mode.stderr index c5bc92e37b5..7ad88471d5a 100644 --- a/src/test/ui/parser/removed-syntax-mode.stderr +++ b/src/test/ui/parser/removed-syntax-mode.stderr @@ -1,11 +1,8 @@ -error: expected pattern, found `+` +error: expected argument name, found `+` --> $DIR/removed-syntax-mode.rs:13:6 | -LL | fn f(+x: isize) {} //~ ERROR expected pattern, found `+` - | ^ - | | - | expected pattern - | expected argument name +LL | fn f(+x: isize) {} + | ^ expected argument name error: aborting due to previous error diff --git a/src/test/ui/self/self-vs-path-ambiguity.stderr b/src/test/ui/self/self-vs-path-ambiguity.stderr index 4cad8401f23..76517433170 100644 --- a/src/test/ui/self/self-vs-path-ambiguity.stderr +++ b/src/test/ui/self/self-vs-path-ambiguity.stderr @@ -2,10 +2,7 @@ error: unexpected lifetime `'a` in pattern --> $DIR/self-vs-path-ambiguity.rs:19:11 | LL | fn i(&'a self::S: &S) {} //~ ERROR unexpected lifetime `'a` in pattern - | ^^ - | | - | unexpected lifetime - | expected argument name + | ^^ unexpected lifetime error: aborting due to previous error -- 2.44.0