Skip to content

Commit ad5dfec

Browse files
committed
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.
2 parents 2564711 + dedb7bb commit ad5dfec

13 files changed

+128
-20
lines changed

src/libsyntax/parse/parser.rs

+26-13
Original file line numberDiff line numberDiff line change
@@ -551,20 +551,33 @@ impl<'a> Parser<'a> {
551551
expected.dedup();
552552
let expect = tokens_to_string(&expected[..]);
553553
let actual = self.this_token_to_string();
554-
Err(self.fatal(
555-
&(if expected.len() > 1 {
556-
(format!("expected one of {}, found `{}`",
557-
expect,
558-
actual))
559-
} else if expected.is_empty() {
560-
(format!("unexpected token: `{}`",
561-
actual))
554+
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
555+
let short_expect = if expected.len() > 6 {
556+
format!("{} possible tokens", expected.len())
562557
} else {
563-
(format!("expected {}, found `{}`",
564-
expect,
565-
actual))
566-
})[..]
567-
))
558+
expect.clone()
559+
};
560+
(format!("expected one of {}, found `{}`", expect, actual),
561+
(self.prev_span.next_point(), format!("expected one of {} here", short_expect)))
562+
} else if expected.is_empty() {
563+
(format!("unexpected token: `{}`", actual),
564+
(self.prev_span, "unexpected token after this".to_string()))
565+
} else {
566+
(format!("expected {}, found `{}`", expect, actual),
567+
(self.prev_span.next_point(), format!("expected {} here", expect)))
568+
};
569+
let mut err = self.fatal(&msg_exp);
570+
let sp = if self.token == token::Token::Eof {
571+
// This is EOF, don't want to point at the following char, but rather the last token
572+
self.prev_span
573+
} else {
574+
label_sp
575+
};
576+
err.span_label(sp, &label_exp);
577+
if !sp.source_equal(&self.span) {
578+
err.span_label(self.span, &"unexpected token");
579+
}
580+
Err(err)
568581
}
569582
}
570583

src/libsyntax_pos/lib.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,13 @@ impl Span {
8383
/// Returns a new span representing just the end-point of this span
8484
pub fn end_point(self) -> Span {
8585
let lo = cmp::max(self.hi.0 - 1, self.lo.0);
86-
Span { lo: BytePos(lo), hi: self.hi, ctxt: self.ctxt }
86+
Span { lo: BytePos(lo), ..self }
87+
}
88+
89+
/// Returns a new span representing the next character after the end-point of this span
90+
pub fn next_point(self) -> Span {
91+
let lo = cmp::max(self.hi.0, self.lo.0 + 1);
92+
Span { lo: BytePos(lo), hi: BytePos(lo + 1), ..self }
8793
}
8894

8995
/// Returns `self` if `self` is not the dummy span, and `other` otherwise.

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

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

1921
println!("{}", foo)
2022
}

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ 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-
| ^
17+
| ^ expected one of `,`, `.`, `?`, or an operator here
1818

1919
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
2020
--> $DIR/token-error-correct-3.rs:29:9
2121
|
22+
25 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
23+
| - expected one of `.`, `;`, `?`, `}`, or an operator here
24+
...
2225
29 | } else { //~ ERROR: incorrect close delimiter: `}`
23-
| ^
26+
| ^ unexpected token
2427

2528
error[E0425]: cannot find function `is_directory` in this scope
2629
--> $DIR/token-error-correct-3.rs:21:13

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ error: expected one of `)`, `,`, `.`, `<`, `?`, `break`, `continue`, `false`, `f
3232
--> $DIR/token-error-correct.rs:14:13
3333
|
3434
14 | foo(bar(;
35-
| ^
35+
| ^ expected one of 18 possible tokens here
3636

3737
error: expected expression, found `)`
3838
--> $DIR/token-error-correct.rs:23:1

src/test/parse-fail/bounds-obj-parens.rs renamed to src/test/ui/token/bounds-obj-parens.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212

1313
type A = Box<(Fn(D::Error) -> E) + 'static + Send + Sync>; // OK (but see #39318)
1414

15-
FAIL //~ ERROR
15+
FAIL
16+
//~^ ERROR
17+
//~| ERROR
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
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
8+

src/test/compile-fail/issue-10636-2.rs renamed to src/test/ui/token/issue-10636-2.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@
1414
pub fn trace_option(option: Option<isize>) {
1515
option.map(|some| 42; //~ NOTE: unclosed delimiter
1616
//~^ ERROR: expected one of
17+
//~| NOTE: expected one of
18+
//~| NOTE: unexpected token
1719
} //~ ERROR: incorrect close delimiter
1820
//~^ ERROR: expected expression, found `)`
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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
28+

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

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ 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 here
24+
//~| NOTE unexpected token
2325
2 )
2426
}
2527

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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
32+

src/test/parse-fail/trailing-plus-in-bounds.rs renamed to src/test/ui/token/trailing-plus-in-bounds.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ fn main() {
1616
let x: Box<Debug+> = box 3 as Box<Debug+>; // Trailing `+` is OK
1717
}
1818

19-
FAIL //~ ERROR
19+
FAIL
20+
//~^ ERROR
21+
//~| ERROR
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected one of `!` or `::`, found `<eof>`
2+
--> $DIR/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
8+

0 commit comments

Comments
 (0)