Skip to content

Commit 78ae8fe

Browse files
committed
Improve wording and spans for unexpected token
* Point at where the token was expected instead of the last token successfuly parsed. * Only show `unexpected token` if the next char and the unexpected token don't have the same span. * Change some cfail and pfail tests to ui test. * Don't show all possible tokens in span label if they are more than 6.
1 parent 03eca71 commit 78ae8fe

13 files changed

+102
-15
lines changed

src/libsyntax/parse/parser.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -548,19 +548,32 @@ impl<'a> Parser<'a> {
548548
expected.dedup();
549549
let expect = tokens_to_string(&expected[..]);
550550
let actual = self.this_token_to_string();
551-
let (msg_exp, label_exp) = if expected.len() > 1 {
551+
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
552+
let short_expect = if expected.len() > 6 {
553+
format!("{} possible tokens", expected.len())
554+
} else {
555+
expect.clone()
556+
};
552557
(format!("expected one of {}, found `{}`", expect, actual),
553-
format!("expected one of {} after this", expect))
558+
(self.prev_span.next_point(), format!("expected one of {} here", short_expect)))
554559
} else if expected.is_empty() {
555560
(format!("unexpected token: `{}`", actual),
556-
"unexpected token after this".to_string())
561+
(self.prev_span, "unexpected token after this".to_string()))
557562
} else {
558563
(format!("expected {}, found `{}`", expect, actual),
559-
format!("expected {} after this", expect))
564+
(self.prev_span.next_point(), format!("expected {} here", expect)))
560565
};
561566
let mut err = self.fatal(&msg_exp);
562-
err.span_label(self.prev_span, &label_exp);
563-
err.span_label(self.span, &"unexpected token");
567+
let sp = if self.token == token::Token::Eof {
568+
// This is EOF, don't want to point at the following char, but rather the last token
569+
self.prev_span
570+
} else {
571+
label_sp
572+
};
573+
err.span_label(sp, &label_exp);
574+
if label_sp != self.span {
575+
err.span_label(self.span, &"unexpected token");
576+
}
564577
Err(err)
565578
}
566579
}

src/libsyntax_pos/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ impl Span {
7979
Span { lo: BytePos(lo), hi: self.hi, expn_id: self.expn_id}
8080
}
8181

82+
/// Returns a new span representing the next character after the end-point of this span
83+
pub fn next_point(self) -> Span {
84+
let lo = BytePos(cmp::max(self.hi.0, self.lo.0 + 1));
85+
Span { lo: lo, hi: lo, expn_id: self.expn_id}
86+
}
87+
8288
/// Returns `self` if `self` is not the dummy span, and `other` otherwise.
8389
pub fn substitute_dummy(self, other: Span) -> Span {
8490
if self.source_equal(&DUMMY_SP) { other } else { self }

src/test/parse-fail/match-refactor-to-expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() {
1414
let foo =
1515
match //~ NOTE did you mean to remove this `match` keyword?
1616
Some(4).unwrap_or_else(5)
17-
//~^ NOTE expected one of `.`, `?`, `{`, or an operator after this
17+
//~^ NOTE expected one of `.`, `?`, `{`, or an operator here
1818
; //~ NOTE unexpected token
1919
//~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
2020

src/test/ui/resolve/token-error-correct-3.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@ error: expected one of `,`, `.`, `?`, or an operator, found `;`
1414
--> $DIR/token-error-correct-3.rs:23:35
1515
|
1616
23 | callback(path.as_ref(); //~ NOTE: unclosed delimiter
17-
| -^ unexpected token
18-
| |
19-
| expected one of `,`, `.`, `?`, or an operator after this
17+
| ^ expected one of `,`, `.`, `?`, or an operator here
2018

2119
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
2220
--> $DIR/token-error-correct-3.rs:29:9
2321
|
2422
25 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
25-
| - expected one of `.`, `;`, `?`, `}`, or an operator after this
23+
| - expected one of `.`, `;`, `?`, `}`, or an operator here
2624
...
2725
29 | } else { //~ ERROR: incorrect close delimiter: `}`
2826
| ^ unexpected token

src/test/ui/resolve/token-error-correct.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ error: expected one of `)`, `,`, `.`, `<`, `?`, `break`, `continue`, `false`, `f
3232
--> $DIR/token-error-correct.rs:14:13
3333
|
3434
14 | foo(bar(;
35-
| -^ unexpected token
36-
| |
37-
| expected one of `)`, `,`, `.`, `<`, `?`, `break`, `continue`, `false`, `for`, `if`, `loop`, `match`, `move`, `return`, `true`, `unsafe`, `while`, or an operator after this
35+
| ^ expected one of 18 possible tokens here
3836

3937
error: expected expression, found `)`
4038
--> $DIR/token-error-correct.rs:23:1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: expected one of `!` or `::`, found `<eof>`
2+
--> $DIR/bounds-obj-parens.rs:15:1
3+
|
4+
15 | FAIL
5+
| ^^^^ expected one of `!` or `::` here
6+
7+
error: aborting due to previous error
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error: incorrect close delimiter: `}`
2+
--> $DIR/issue-10636-2.rs:19:1
3+
|
4+
19 | } //~ ERROR: incorrect close delimiter
5+
| ^
6+
|
7+
note: unclosed delimiter
8+
--> $DIR/issue-10636-2.rs:15:15
9+
|
10+
15 | option.map(|some| 42; //~ NOTE: unclosed delimiter
11+
| ^
12+
13+
error: expected one of `,`, `.`, `?`, or an operator, found `;`
14+
--> $DIR/issue-10636-2.rs:15:25
15+
|
16+
15 | option.map(|some| 42; //~ NOTE: unclosed delimiter
17+
| ^ expected one of `,`, `.`, `?`, or an operator here
18+
19+
error: expected expression, found `)`
20+
--> $DIR/issue-10636-2.rs:19:1
21+
|
22+
19 | } //~ ERROR: incorrect close delimiter
23+
| ^
24+
25+
error: main function not found
26+
27+
error: aborting due to 4 previous errors

src/test/compile-fail/macro-incomplete-parse.rs renamed to src/test/ui/token/macro-incomplete-parse.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ macro_rules! ignored_item {
2020

2121
macro_rules! ignored_expr {
2222
() => ( 1, //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
23-
//~^ NOTE expected one of `.`, `;`, `?`, `}`, or an operator after this
23+
//~^ NOTE expected one of `.`, `;`, `?`, `}`, or an operator here
2424
//~| NOTE unexpected token
2525
2 )
2626
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: macro expansion ignores token `,` and any following
2+
--> $DIR/macro-incomplete-parse.rs:17:9
3+
|
4+
17 | , //~ ERROR macro expansion ignores token `,`
5+
| ^
6+
|
7+
note: caused by the macro expansion here; the usage of `ignored_item!` is likely invalid in item context
8+
--> $DIR/macro-incomplete-parse.rs:32:1
9+
|
10+
32 | ignored_item!(); //~ NOTE caused by the macro expansion here
11+
| ^^^^^^^^^^^^^^^^
12+
13+
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
14+
--> $DIR/macro-incomplete-parse.rs:22:14
15+
|
16+
22 | () => ( 1, //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
17+
| ^ expected one of `.`, `;`, `?`, `}`, or an operator here
18+
19+
error: macro expansion ignores token `,` and any following
20+
--> $DIR/macro-incomplete-parse.rs:29:14
21+
|
22+
29 | () => ( 1, 2 ) //~ ERROR macro expansion ignores token `,`
23+
| ^
24+
|
25+
note: caused by the macro expansion here; the usage of `ignored_pat!` is likely invalid in pattern context
26+
--> $DIR/macro-incomplete-parse.rs:37:9
27+
|
28+
37 | ignored_pat!() => (), //~ NOTE caused by the macro expansion here
29+
| ^^^^^^^^^^^^^^
30+
31+
error: aborting due to 3 previous errors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: expected one of `!` or `::`, found `<eof>`
2+
--> ../../src/test/ui/token/trailing-plus-in-bounds.rs:19:1
3+
|
4+
19 | FAIL
5+
| ^^^^ expected one of `!` or `::` here
6+
7+
error: aborting due to previous error

0 commit comments

Comments
 (0)