]> git.lizzy.rs Git - rust.git/commitdiff
syntax: Make `is_path_start` precise and improve some error messages about unexpected...
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Wed, 20 Apr 2016 23:03:29 +0000 (02:03 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sun, 24 Apr 2016 17:59:44 +0000 (20:59 +0300)
25 files changed:
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/test/compile-fail/fail-simple.rs
src/test/compile-fail/issue-10636-2.rs
src/test/compile-fail/issue-31804.rs
src/test/compile-fail/macro-context.rs
src/test/compile-fail/macro-incomplete-parse.rs
src/test/compile-fail/reserved-become.rs
src/test/compile-fail/token-error-correct.rs
src/test/compile-fail/vec-macro-with-comma-only.rs
src/test/parse-fail/issue-14303-path.rs
src/test/parse-fail/issue-32505.rs
src/test/parse-fail/keyword-abstract.rs
src/test/parse-fail/keyword-final.rs
src/test/parse-fail/keyword-override.rs
src/test/parse-fail/keyword-typeof.rs
src/test/parse-fail/keywords-followed-by-double-colon.rs
src/test/parse-fail/match-arrows-block-then-binop.rs
src/test/parse-fail/obsolete-proc.rs
src/test/parse-fail/removed-syntax-mode.rs
src/test/parse-fail/removed-syntax-mut-vec-expr.rs
src/test/parse-fail/removed-syntax-mut-vec-ty.rs
src/test/parse-fail/removed-syntax-uniq-mut-expr.rs
src/test/parse-fail/removed-syntax-uniq-mut-ty.rs
src/test/parse-fail/unsized2.rs

index a4d2c5b611064d48e94b3deac78ae41fd390cd85..7842d9dca53639697929eb43c81fb4bf810a0020 100644 (file)
@@ -394,6 +394,17 @@ pub fn this_token_to_string(&self) -> String {
         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<T>(&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 @@ pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
                  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 @@ pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
             // 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 @@ pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::E
     }
 
     /// 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 @@ pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, LitKind> {
                         (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 @@ pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, LitKind> {
                 };
 
                 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 @@ pub fn parse_lit(&mut self) -> PResult<'a, Lit> {
         } 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 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                     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 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                     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 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPa
     }
 
     fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
-        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 @@ fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
         }
     }
 
-    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<Pat>> {
         maybe_whole!(self, NtPat);
@@ -3641,7 +3655,7 @@ pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
                 // 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 @@ pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
                 }
             } 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));
+                    }
                 }
             }
           }
index 32078c875be32fbc3f078b9b47f2a14ea7995728..fcb6c3539db5931be0219ceee5f7f700c2f8111d 100644 (file)
@@ -243,6 +243,11 @@ pub fn is_mutability(&self) -> bool {
         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<BinOpKind> {
         match *self {
index 97b709592a9c9434487e739fb6804aeaeac595c4..e889d35477059c9ac69f501f81a58c271ae03972 100644 (file)
@@ -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 `@`
 }
index 747252d59241ea21854763f38da3c5010f3c363c..beaf9e5059fa232bead2bb0823e178e9f319e3b3 100644 (file)
@@ -15,4 +15,4 @@ pub fn trace_option(option: Option<isize>) {
     option.map(|some| 42; //~ NOTE: unclosed delimiter
                           //~^ ERROR: expected one of
 } //~ ERROR: incorrect close delimiter
-//~^ ERROR: unexpected token
+//~^ ERROR: expected expression, found `)`
index b6a04bee85d4faada3cd72a60121f4043e3b2474..cea52b11c5ded3606b350fd4001cc289858c1dbb 100644 (file)
@@ -13,4 +13,4 @@
 
 fn main() {
     let
-} //~ ERROR unexpected token: `}`
+} //~ ERROR expected pattern, found `}`
index 8fa5e0a70890ed2abf328ea6559dcdd5ec152fe2..5d07f0747ff435316db7367cd4ea210baa74e02d 100644 (file)
@@ -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 `;`
index 0d5f9079649c4688631a578df61032167b5a0a05..8d515622e53ff5aa0f0967d99575c3f3a7c9822e 100644 (file)
@@ -19,7 +19,7 @@ fn bar() {}
 }
 
 macro_rules! ignored_expr {
-    () => ( 1,  //~ ERROR unexpected token: `,`
+    () => ( 1,  //~ ERROR expected expression, found `,`
             2 )
 }
 
index 82e9ebc10d1c8ebeed6fca10b6bdbe12d8aa8874..bcda61e363def603cda29af5e64f29c479caae54 100644 (file)
@@ -10,5 +10,5 @@
 
 fn main() {
     let become = 0;
-    //~^ ERROR `become` is a reserved keyword
+    //~^ ERROR expected pattern, found reserved keyword `become`
 }
index 6c54acd7bdbf60827ec5a665ac15d29b0a6ce12f..f5fecf3e1740a8197d0d3f3d2386dac38f1f9227 100644 (file)
 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 `)`
index 8c8e789cd9640058bfb45cc1f4584ece0c9963e1..346cf1ec555d3853776c0e8ff425e058eb69f200 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    vec!(,); //~ ERROR unexpected token
+    vec!(,); //~ ERROR expected expression, found `,`
 }
index 7c30b5f26296ba0ef0583de657fc0b95742f08f4..431a917c2d9f4cd9f76633c4a4e48f73e4d9d55f 100644 (file)
@@ -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`
index e697e98bc06072bcf0400e244208cbc5f8cc40d5..246941ff2597dace033288dc3ea1fb70d8579ea4 100644 (file)
@@ -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() { }
index bd3fbbe79a88bcc1746419026cef60113504ca2c..2db5a5c583ac33b55366b22c92d4a78628b2f1b3 100644 (file)
@@ -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`
 }
index 4b06312d0993bac2215b817d61c1a618ebc483bb..be29a739443e60581e793703d66828a44af1326e 100644 (file)
@@ -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`
 }
index 3f79e437189c2700181a1f9784f6f5ed41040a1a..60333762b33e087e848de71688c2d6b544c638b5 100644 (file)
@@ -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`
 }
index 29ec4f5844b1e5e2052fdb0ff1af7e61372c0cde..40e26bd375ae50b8efe12a52af0fe0832bb3a972 100644 (file)
@@ -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`
 }
index 5e27d3e4f383ebd10c1920c97cd54ed17f86f5ba..bb8a1dfdb19063485201351b6b11250080446486 100644 (file)
@@ -12,5 +12,5 @@
 
 fn main() {
     struct::foo();  //~ ERROR expected identifier
-    mut::baz(); //~ ERROR expected identifier
+    mut::baz(); //~ ERROR expected expression, found keyword `mut`
 }
index 3026e159a44395b2d5d75483bbecd9ecab0e01e7..e8cfb77f059634aa77b584cf2c08b6883e7dd4fd 100644 (file)
@@ -14,6 +14,6 @@ fn main() {
 
     match 0 {
       0 => {
-      } + 5 //~ ERROR unexpected token: `+`
+      } + 5 //~ ERROR expected pattern, found `+`
     }
 }
index 1ef8cd2714d7f4124d134384e44904bd9dc21c08..648c46d246cbcb026f7734392a5544cfcad8b6c3 100644 (file)
@@ -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() { }
index 4dafc36e912c58385c003629eed00fde14bbaef8..6e99f8b3eeadc74f693c108b270c61fa06fdb36c 100644 (file)
@@ -10,4 +10,4 @@
 
 // compile-flags: -Z parse-only
 
-fn f(+x: isize) {} //~ ERROR unexpected token: `+`
+fn f(+x: isize) {} //~ ERROR expected pattern, found `+`
index 301bd0e8b1c9c08e94179a05761d0e1e8d6ccf0e..7e5bd27b497cbe1eabba462dc65ac1269246c806 100644 (file)
@@ -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`
 }
index 91918f01bb03e760f16e542d5f8a6fb243b65eb2..0cdf1981a231bd82759aa7785db4b78bf3dd31ba 100644 (file)
@@ -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`
index 2f637cf0b4e7633d63a1eaf8dd5546a3f6ce576d..b16c77ab6b5befbe10505abf556f2773758d0389 100644 (file)
@@ -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`
 }
index e1637901266e04ea4eace764054e65dd58dccac1..9bd8dc9b11b216cf9074e55b656095c23988cfd7 100644 (file)
@@ -10,6 +10,4 @@
 
 // compile-flags: -Z parse-only
 
-type mut_box = Box<mut isize>;
-    //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `isize`
+type mut_box = Box<mut isize>; //~ ERROR expected type, found keyword `mut`
index a4a4c0dcfd91602fd16256ba193201ea2e91fc71..f3af8740be9483f23a73254f3e56838107e67725 100644 (file)
@@ -15,8 +15,5 @@
 fn f<X>() {}
 
 pub fn main() {
-    f<type>();
-    //~^ ERROR expected identifier, found keyword `type`
-    //~^^ ERROR: chained comparison
-    //~^^^ HELP: use `::<
+    f<type>(); //~ ERROR expected expression, found keyword `type`
 }