Skip to content

Commit 992b914

Browse files
committed
Recover from X<Y,Z> when parsing const expr
This adds recovery when in array type syntax user writes [X; Y<Z, ...>] instead of [X; Y::<Z, ...>] Fixes #82566 Note that whenever we parse an expression and know that the next token cannot be `,`, we should be calling check_mistyped_turbofish_with_multiple_type_params for this recovery. Previously we only did this for statement parsing (e.g. `let x = f<a, b>;`). We now also do it when parsing the length field in array type syntax.
1 parent fb631a5 commit 992b914

File tree

5 files changed

+79
-5
lines changed

5 files changed

+79
-5
lines changed

compiler/rustc_parse/src/parser/ty.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,20 @@ impl<'a> Parser<'a> {
360360
}
361361
Err(err) => return Err(err),
362362
};
363+
363364
let ty = if self.eat(&token::Semi) {
364-
TyKind::Array(elt_ty, self.parse_anon_const_expr()?)
365+
let mut length = self.parse_anon_const_expr()?;
366+
if let Err(e) = self.expect(&token::CloseDelim(token::Bracket)) {
367+
// Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
368+
self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?;
369+
self.expect(&token::CloseDelim(token::Bracket))?;
370+
}
371+
TyKind::Array(elt_ty, length)
365372
} else {
373+
self.expect(&token::CloseDelim(token::Bracket))?;
366374
TyKind::Slice(elt_ty)
367375
};
368-
self.expect(&token::CloseDelim(token::Bracket))?;
376+
369377
Ok(ty)
370378
}
371379

src/test/ui/suggestions/issue-82566.stderr src/test/ui/suggestions/issue-82566-1.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: comparison operators cannot be chained
2-
--> $DIR/issue-82566.rs:18:7
2+
--> $DIR/issue-82566-1.rs:18:7
33
|
44
LL | T1<1>::C;
55
| ^ ^
@@ -10,7 +10,7 @@ LL | T1::<1>::C;
1010
| ^^
1111

1212
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
13-
--> $DIR/issue-82566.rs:19:9
13+
--> $DIR/issue-82566-1.rs:19:9
1414
|
1515
LL | T2<1, 2>::C;
1616
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
@@ -21,7 +21,7 @@ LL | T2::<1, 2>::C;
2121
| ^^
2222

2323
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
24-
--> $DIR/issue-82566.rs:20:9
24+
--> $DIR/issue-82566-1.rs:20:9
2525
|
2626
LL | T3<1, 2, 3>::C;
2727
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
struct Foo1<const N1: usize>;
2+
struct Foo2<const N1: usize, const N2: usize>;
3+
struct Foo3<const N1: usize, const N2: usize, const N3: usize>;
4+
5+
impl<const N1: usize> Foo1<N1> {
6+
const SUM: usize = N1;
7+
}
8+
9+
impl<const N1: usize, const N2: usize> Foo2<N1, N2> {
10+
const SUM: usize = N1 + N2;
11+
}
12+
13+
impl<const N1: usize, const N2: usize, const N3: usize> Foo3<N1, N2, N3> {
14+
const SUM: usize = N1 + N2 + N3;
15+
}
16+
17+
fn foo1() -> [(); Foo1<10>::SUM] { //~ ERROR: comparison operators cannot be chained
18+
todo!()
19+
}
20+
21+
fn foo2() -> [(); Foo2<10, 20>::SUM] {
22+
//~^ ERROR: expected one of `.`, `?`, `]`, or an operator, found `,`
23+
todo!()
24+
}
25+
26+
fn foo3() -> [(); Foo3<10, 20, 30>::SUM] {
27+
//~^ ERROR: expected one of `.`, `?`, `]`, or an operator, found `,`
28+
todo!()
29+
}
30+
31+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error: comparison operators cannot be chained
2+
--> $DIR/issue-82566-2.rs:17:23
3+
|
4+
LL | fn foo1() -> [(); Foo1<10>::SUM] {
5+
| ^ ^
6+
|
7+
help: use `::<...>` instead of `<...>` to specify type or const arguments
8+
|
9+
LL | fn foo1() -> [(); Foo1::<10>::SUM] {
10+
| ^^
11+
12+
error: expected one of `.`, `?`, `]`, or an operator, found `,`
13+
--> $DIR/issue-82566-2.rs:21:26
14+
|
15+
LL | fn foo2() -> [(); Foo2<10, 20>::SUM] {
16+
| ^ expected one of `.`, `?`, `]`, or an operator
17+
|
18+
help: use `::<...>` instead of `<...>` to specify type or const arguments
19+
|
20+
LL | fn foo2() -> [(); Foo2::<10, 20>::SUM] {
21+
| ^^
22+
23+
error: expected one of `.`, `?`, `]`, or an operator, found `,`
24+
--> $DIR/issue-82566-2.rs:26:26
25+
|
26+
LL | fn foo3() -> [(); Foo3<10, 20, 30>::SUM] {
27+
| ^ expected one of `.`, `?`, `]`, or an operator
28+
|
29+
help: use `::<...>` instead of `<...>` to specify type or const arguments
30+
|
31+
LL | fn foo3() -> [(); Foo3::<10, 20, 30>::SUM] {
32+
| ^^
33+
34+
error: aborting due to 3 previous errors
35+

0 commit comments

Comments
 (0)