Skip to content

Commit 2228f73

Browse files
committed
Suggest use ; to construct array type when other token exists
Signed-off-by: xizheyin <[email protected]>
1 parent 6963621 commit 2228f73

File tree

7 files changed

+86
-19
lines changed

7 files changed

+86
-19
lines changed

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,14 +575,46 @@ impl<'a> Parser<'a> {
575575
self.expect(exp!(CloseBracket))?;
576576
}
577577
TyKind::Array(elt_ty, length)
578-
} else {
579-
self.expect(exp!(CloseBracket))?;
578+
} else if self.eat(exp!(CloseBracket)) {
580579
TyKind::Slice(elt_ty)
580+
} else {
581+
let span = self.token.span;
582+
let token_descr = super::token_descr(&self.token);
583+
self.suggest_array_ty(span, token_descr)?
581584
};
582585

583586
Ok(ty)
584587
}
585588

589+
/// Suggest with malformed array type syntax.
590+
///
591+
/// This method attempts to suggest with cases like:
592+
/// - `[u8, 5]` → suggests using `;`
593+
/// Consider to add more cases in the future.
594+
fn suggest_array_ty(&mut self, span: Span, token_descr: String) -> PResult<'a, TyKind> {
595+
let mut err =
596+
self.dcx().struct_span_err(span, format!("expected `;` or `]`, found {}", token_descr));
597+
err.span_label(span, "expected `;` or `]`");
598+
err.note("you might need a array type or a slice type");
599+
600+
let mut snapshot = self.create_snapshot_for_diagnostic();
601+
snapshot.bump();
602+
if let Err(e) = snapshot.parse_expr_anon_const() {
603+
e.cancel();
604+
return Err(err);
605+
}
606+
err.span_suggestion_verbose(
607+
span,
608+
"you might have meant to use `;` as the separator",
609+
";",
610+
Applicability::MaybeIncorrect,
611+
);
612+
if let Err(e) = snapshot.expect(exp!(CloseBracket)) {
613+
e.cancel();
614+
}
615+
Err(err)
616+
}
617+
586618
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
587619
let and_span = self.prev_token.span;
588620
let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());

tests/ui/parser/better-expected.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
fn main() {
2-
let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
2+
let x: [isize 3]; //~ ERROR expected `;` or `]`, found `3`
33
}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
1+
error: expected `;` or `]`, found `3`
22
--> $DIR/better-expected.rs:2:19
33
|
44
LL | let x: [isize 3];
5-
| - ^ expected one of 7 possible tokens
5+
| - ^ expected `;` or `]`
66
| |
77
| while parsing the type for `x`
8+
|
9+
= note: you might need a array type or a slice type
810

911
error: aborting due to 1 previous error
1012

tests/ui/parser/recover/array-type-no-semi.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
fn main() {
66
let x = 5;
77
let b: [i32, 5];
8-
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
8+
//~^ ERROR expected `;` or `]`, found `,`
99
//~| ERROR expected value, found builtin type `i32` [E0423]
1010
let a: [i32, ];
11-
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
11+
//~^ ERROR expected `;` or `]`, found `,`
1212
//~| ERROR expected value, found builtin type `i32` [E0423]
1313
let c: [i32, x];
14-
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
14+
//~^ ERROR expected `;` or `]`, found `,`
1515
//~| ERROR expected value, found builtin type `i32` [E0423]
1616

1717
}

tests/ui/parser/recover/array-type-no-semi.stderr

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,53 @@
1-
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
1+
error: expected `;` or `]`, found `,`
22
--> $DIR/array-type-no-semi.rs:7:16
33
|
44
LL | let b: [i32, 5];
5-
| - ^ expected one of 7 possible tokens
5+
| - ^ expected `;` or `]`
66
| |
77
| while parsing the type for `b`
8-
| help: use `=` if you meant to assign
8+
|
9+
= note: you might need a array type or a slice type
10+
help: you might have meant to use `;` as the separator
11+
|
12+
LL - let b: [i32, 5];
13+
LL + let b: [i32; 5];
14+
|
15+
help: use `=` if you meant to assign
16+
|
17+
LL - let b: [i32, 5];
18+
LL + let b = [i32, 5];
19+
|
920

10-
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
21+
error: expected `;` or `]`, found `,`
1122
--> $DIR/array-type-no-semi.rs:10:16
1223
|
1324
LL | let a: [i32, ];
14-
| - ^ expected one of 7 possible tokens
25+
| - ^ expected `;` or `]`
1526
| |
1627
| while parsing the type for `a`
1728
| help: use `=` if you meant to assign
29+
|
30+
= note: you might need a array type or a slice type
1831

19-
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
32+
error: expected `;` or `]`, found `,`
2033
--> $DIR/array-type-no-semi.rs:13:16
2134
|
2235
LL | let c: [i32, x];
23-
| - ^ expected one of 7 possible tokens
36+
| - ^ expected `;` or `]`
2437
| |
2538
| while parsing the type for `c`
26-
| help: use `=` if you meant to assign
39+
|
40+
= note: you might need a array type or a slice type
41+
help: you might have meant to use `;` as the separator
42+
|
43+
LL - let c: [i32, x];
44+
LL + let c: [i32; x];
45+
|
46+
help: use `=` if you meant to assign
47+
|
48+
LL - let c: [i32, x];
49+
LL + let c = [i32, x];
50+
|
2751

2852
error[E0423]: expected value, found builtin type `i32`
2953
--> $DIR/array-type-no-semi.rs:7:13
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
1+
type v = [isize * 3]; //~ ERROR expected `;` or `]`, found `*`
2+
3+
fn main() {}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
1+
error: expected `;` or `]`, found `*`
22
--> $DIR/removed-syntax-fixed-vec.rs:1:17
33
|
44
LL | type v = [isize * 3];
5-
| ^ expected one of 7 possible tokens
5+
| ^ expected `;` or `]`
6+
|
7+
= note: you might need a array type or a slice type
8+
help: you might have meant to use `;` as the separator
9+
|
10+
LL - type v = [isize * 3];
11+
LL + type v = [isize ; 3];
12+
|
613

714
error: aborting due to 1 previous error
815

0 commit comments

Comments
 (0)