about summary refs log tree commit diff
path: root/src/libsyntax/parse
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/libsyntax/parse
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/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs39
1 files changed, 26 insertions, 13 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)
         }
     }