about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-04-05 09:23:27 +0000
committerbors <bors@rust-lang.org>2017-04-05 09:23:27 +0000
commitad5dfecc6ae23bb7d2b8075d705011918ab4f399 (patch)
tree134a798c167e4b83e6caed352b73f94864ce2606 /src
parent2564711e803f62e04bebf10408cc1c11297c0caf (diff)
parentdedb7bbbbf272226f327b8cda8aaa12cf6325eca (diff)
downloadrust-ad5dfecc6ae23bb7d2b8075d705011918ab4f399.tar.gz
rust-ad5dfecc6ae23bb7d2b8075d705011918ab4f399.zip
Auto merge of #40811 - estebank:issue-32540, r=jonathandturner
Point at last valid token on failed `expect_one_of`

```rust
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
  --> $DIR/token-error-correct-3.rs:29:9
   |
25 |         foo()
   |              - expected one of `.`, `;`, `?`, `}`, or an operator after this
...
29 |     } else {
   |     ^ unexpected token
```

Fix #32540.
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs39
-rw-r--r--src/libsyntax_pos/lib.rs8
-rw-r--r--src/test/parse-fail/match-refactor-to-expr.rs4
-rw-r--r--src/test/ui/resolve/token-error-correct-3.stderr7
-rw-r--r--src/test/ui/resolve/token-error-correct.stderr2
-rw-r--r--src/test/ui/token/bounds-obj-parens.rs (renamed from src/test/parse-fail/bounds-obj-parens.rs)4
-rw-r--r--src/test/ui/token/bounds-obj-parens.stderr8
-rw-r--r--src/test/ui/token/issue-10636-2.rs (renamed from src/test/compile-fail/issue-10636-2.rs)2
-rw-r--r--src/test/ui/token/issue-10636-2.stderr28
-rw-r--r--src/test/ui/token/macro-incomplete-parse.rs (renamed from src/test/compile-fail/macro-incomplete-parse.rs)2
-rw-r--r--src/test/ui/token/macro-incomplete-parse.stderr32
-rw-r--r--src/test/ui/token/trailing-plus-in-bounds.rs (renamed from src/test/parse-fail/trailing-plus-in-bounds.rs)4
-rw-r--r--src/test/ui/token/trailing-plus-in-bounds.stderr8
13 files changed, 128 insertions, 20 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index c2c3e5a6855..a27fc070ebe 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -551,20 +551,33 @@ impl<'a> Parser<'a> {
             expected.dedup();
             let expect = tokens_to_string(&expected[..]);
             let actual = self.this_token_to_string();
-            Err(self.fatal(
-                &(if expected.len() > 1 {
-                    (format!("expected one of {}, found `{}`",
-                             expect,
-                             actual))
-                } else if expected.is_empty() {
-                    (format!("unexpected token: `{}`",
-                             actual))
+            let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
+                let short_expect = if expected.len() > 6 {
+                    format!("{} possible tokens", expected.len())
                 } else {
-                    (format!("expected {}, found `{}`",
-                             expect,
-                             actual))
-                })[..]
-            ))
+                    expect.clone()
+                };
+                (format!("expected one of {}, found `{}`", expect, actual),
+                 (self.prev_span.next_point(), format!("expected one of {} here", short_expect)))
+            } else if expected.is_empty() {
+                (format!("unexpected token: `{}`", actual),
+                 (self.prev_span, "unexpected token after this".to_string()))
+            } else {
+                (format!("expected {}, found `{}`", expect, actual),
+                 (self.prev_span.next_point(), format!("expected {} here", expect)))
+            };
+            let mut err = self.fatal(&msg_exp);
+            let sp = if self.token == token::Token::Eof {
+                // This is EOF, don't want to point at the following char, but rather the last token
+                self.prev_span
+            } else {
+                label_sp
+            };
+            err.span_label(sp, &label_exp);
+            if !sp.source_equal(&self.span) {
+                err.span_label(self.span, &"unexpected token");
+            }
+            Err(err)
         }
     }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 947192a0a23..3f09b2009a7 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -83,7 +83,13 @@ impl Span {
     /// Returns a new span representing just the end-point of this span
     pub fn end_point(self) -> Span {
         let lo = cmp::max(self.hi.0 - 1, self.lo.0);
-        Span { lo: BytePos(lo), hi: self.hi, ctxt: self.ctxt }
+        Span { lo: BytePos(lo), ..self }
+    }
+
+    /// Returns a new span representing the next character after the end-point of this span
+    pub fn next_point(self) -> Span {
+        let lo = cmp::max(self.hi.0, self.lo.0 + 1);
+        Span { lo: BytePos(lo), hi: BytePos(lo + 1), ..self }
     }
 
     /// Returns `self` if `self` is not the dummy span, and `other` otherwise.
diff --git a/src/test/parse-fail/match-refactor-to-expr.rs b/src/test/parse-fail/match-refactor-to-expr.rs
index 37b66601e70..e2fee1d1895 100644
--- a/src/test/parse-fail/match-refactor-to-expr.rs
+++ b/src/test/parse-fail/match-refactor-to-expr.rs
@@ -14,7 +14,9 @@ fn main() {
     let foo =
         match //~ NOTE did you mean to remove this `match` keyword?
         Some(4).unwrap_or_else(5)
-        ; //~ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
+        //~^ NOTE expected one of `.`, `?`, `{`, or an operator here
+        ; //~ NOTE unexpected token
+        //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
 
     println!("{}", foo)
 }
diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr
index 5be23d8ca48..849787e383f 100644
--- a/src/test/ui/resolve/token-error-correct-3.stderr
+++ b/src/test/ui/resolve/token-error-correct-3.stderr
@@ -14,13 +14,16 @@ error: expected one of `,`, `.`, `?`, or an operator, found `;`
   --> $DIR/token-error-correct-3.rs:23:35
    |
 23 |             callback(path.as_ref();  //~ NOTE: unclosed delimiter
-   |                                   ^
+   |                                   ^ expected one of `,`, `.`, `?`, or an operator here
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
   --> $DIR/token-error-correct-3.rs:29:9
    |
+25 |             fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
+   |                                                             - expected one of `.`, `;`, `?`, `}`, or an operator here
+...
 29 |         } else { //~ ERROR: incorrect close delimiter: `}`
-   |         ^
+   |         ^ unexpected token
 
 error[E0425]: cannot find function `is_directory` in this scope
   --> $DIR/token-error-correct-3.rs:21:13
diff --git a/src/test/ui/resolve/token-error-correct.stderr b/src/test/ui/resolve/token-error-correct.stderr
index 248a923efaf..226fa6469bc 100644
--- a/src/test/ui/resolve/token-error-correct.stderr
+++ b/src/test/ui/resolve/token-error-correct.stderr
@@ -32,7 +32,7 @@ error: expected one of `)`, `,`, `.`, `<`, `?`, `break`, `continue`, `false`, `f
   --> $DIR/token-error-correct.rs:14:13
    |
 14 |     foo(bar(;
-   |             ^
+   |             ^ expected one of 18 possible tokens here
 
 error: expected expression, found `)`
   --> $DIR/token-error-correct.rs:23:1
diff --git a/src/test/parse-fail/bounds-obj-parens.rs b/src/test/ui/token/bounds-obj-parens.rs
index ad59d4a52d7..02c119cf727 100644
--- a/src/test/parse-fail/bounds-obj-parens.rs
+++ b/src/test/ui/token/bounds-obj-parens.rs
@@ -12,4 +12,6 @@
 
 type A = Box<(Fn(D::Error) -> E) + 'static + Send + Sync>; // OK (but see #39318)
 
-FAIL //~ ERROR
+FAIL
+//~^ ERROR
+//~| ERROR
diff --git a/src/test/ui/token/bounds-obj-parens.stderr b/src/test/ui/token/bounds-obj-parens.stderr
new file mode 100644
index 00000000000..4d60be15eca
--- /dev/null
+++ b/src/test/ui/token/bounds-obj-parens.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found `<eof>`
+  --> $DIR/bounds-obj-parens.rs:15:1
+   |
+15 | FAIL
+   | ^^^^ expected one of `!` or `::` here
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/issue-10636-2.rs b/src/test/ui/token/issue-10636-2.rs
index beaf9e5059f..93759123618 100644
--- a/src/test/compile-fail/issue-10636-2.rs
+++ b/src/test/ui/token/issue-10636-2.rs
@@ -14,5 +14,7 @@
 pub fn trace_option(option: Option<isize>) {
     option.map(|some| 42; //~ NOTE: unclosed delimiter
                           //~^ ERROR: expected one of
+                          //~| NOTE: expected one of
+                          //~| NOTE: unexpected token
 } //~ ERROR: incorrect close delimiter
 //~^ ERROR: expected expression, found `)`
diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr
new file mode 100644
index 00000000000..b0bae1248b9
--- /dev/null
+++ b/src/test/ui/token/issue-10636-2.stderr
@@ -0,0 +1,28 @@
+error: incorrect close delimiter: `}`
+  --> $DIR/issue-10636-2.rs:19:1
+   |
+19 | } //~ ERROR: incorrect close delimiter
+   | ^
+   |
+note: unclosed delimiter
+  --> $DIR/issue-10636-2.rs:15:15
+   |
+15 |     option.map(|some| 42; //~ NOTE: unclosed delimiter
+   |               ^
+
+error: expected one of `,`, `.`, `?`, or an operator, found `;`
+  --> $DIR/issue-10636-2.rs:15:25
+   |
+15 |     option.map(|some| 42; //~ NOTE: unclosed delimiter
+   |                         ^ expected one of `,`, `.`, `?`, or an operator here
+
+error: expected expression, found `)`
+  --> $DIR/issue-10636-2.rs:19:1
+   |
+19 | } //~ ERROR: incorrect close delimiter
+   | ^
+
+error: main function not found
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/compile-fail/macro-incomplete-parse.rs b/src/test/ui/token/macro-incomplete-parse.rs
index c2ac99d1f6a..47374fc3c60 100644
--- a/src/test/compile-fail/macro-incomplete-parse.rs
+++ b/src/test/ui/token/macro-incomplete-parse.rs
@@ -20,6 +20,8 @@ macro_rules! ignored_item {
 
 macro_rules! ignored_expr {
     () => ( 1,  //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+                //~^ NOTE expected one of `.`, `;`, `?`, `}`, or an operator here
+                //~| NOTE unexpected token
             2 )
 }
 
diff --git a/src/test/ui/token/macro-incomplete-parse.stderr b/src/test/ui/token/macro-incomplete-parse.stderr
new file mode 100644
index 00000000000..f23d97586b8
--- /dev/null
+++ b/src/test/ui/token/macro-incomplete-parse.stderr
@@ -0,0 +1,32 @@
+error: macro expansion ignores token `,` and any following
+  --> $DIR/macro-incomplete-parse.rs:17:9
+   |
+17 |         , //~ ERROR macro expansion ignores token `,`
+   |         ^
+   |
+note: caused by the macro expansion here; the usage of `ignored_item!` is likely invalid in item context
+  --> $DIR/macro-incomplete-parse.rs:32:1
+   |
+32 | ignored_item!(); //~ NOTE caused by the macro expansion here
+   | ^^^^^^^^^^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+  --> $DIR/macro-incomplete-parse.rs:22:14
+   |
+22 |     () => ( 1,  //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+   |              ^ expected one of `.`, `;`, `?`, `}`, or an operator here
+
+error: macro expansion ignores token `,` and any following
+  --> $DIR/macro-incomplete-parse.rs:29:14
+   |
+29 |     () => ( 1, 2 ) //~ ERROR macro expansion ignores token `,`
+   |              ^
+   |
+note: caused by the macro expansion here; the usage of `ignored_pat!` is likely invalid in pattern context
+  --> $DIR/macro-incomplete-parse.rs:37:9
+   |
+37 |         ignored_pat!() => (), //~ NOTE caused by the macro expansion here
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/parse-fail/trailing-plus-in-bounds.rs b/src/test/ui/token/trailing-plus-in-bounds.rs
index 4a2e6d5bdcd..2bb2c97790c 100644
--- a/src/test/parse-fail/trailing-plus-in-bounds.rs
+++ b/src/test/ui/token/trailing-plus-in-bounds.rs
@@ -16,4 +16,6 @@ fn main() {
     let x: Box<Debug+> = box 3 as Box<Debug+>; // Trailing `+` is OK
 }
 
-FAIL //~ ERROR
+FAIL
+//~^ ERROR
+//~| ERROR
diff --git a/src/test/ui/token/trailing-plus-in-bounds.stderr b/src/test/ui/token/trailing-plus-in-bounds.stderr
new file mode 100644
index 00000000000..c765a434b8a
--- /dev/null
+++ b/src/test/ui/token/trailing-plus-in-bounds.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found `<eof>`
+  --> $DIR/trailing-plus-in-bounds.rs:19:1
+   |
+19 | FAIL
+   | ^^^^ expected one of `!` or `::` here
+
+error: aborting due to previous error
+