Skip to content

Commit 3d8c5a3

Browse files
authored
Unrolled build for #143905
Rollup merge of #143905 - xizheyin:143828, r=compiler-errors Recover and suggest to use `;` to construct array type Fixes #143828 r? compiler
2 parents a9fb610 + ed88af2 commit 3d8c5a3

File tree

14 files changed

+218
-48
lines changed

14 files changed

+218
-48
lines changed

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,14 +575,69 @@ 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+
self.maybe_recover_array_ty_without_semi(elt_ty)?
581582
};
582583

583584
Ok(ty)
584585
}
585586

587+
/// Recover from malformed array type syntax.
588+
///
589+
/// This method attempts to recover from cases like:
590+
/// - `[u8, 5]` → suggests using `;`, return a Array type
591+
/// - `[u8 5]` → suggests using `;`, return a Array type
592+
/// Consider to add more cases in the future.
593+
fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: P<Ty>) -> PResult<'a, TyKind> {
594+
let span = self.token.span;
595+
let token_descr = super::token_descr(&self.token);
596+
let mut err =
597+
self.dcx().struct_span_err(span, format!("expected `;` or `]`, found {}", token_descr));
598+
err.span_label(span, "expected `;` or `]`");
599+
err.note("you might have meant to write a slice or array type");
600+
601+
// If we cannot recover, return the error immediately.
602+
if !self.may_recover() {
603+
return Err(err);
604+
}
605+
606+
let snapshot = self.create_snapshot_for_diagnostic();
607+
608+
let suggestion_span = if self.eat(exp!(Comma)) || self.eat(exp!(Star)) {
609+
// Consume common erroneous separators.
610+
self.prev_token.span
611+
} else {
612+
self.token.span.shrink_to_lo()
613+
};
614+
615+
// we first try to parse pattern like `[u8 5]`
616+
let length = match self.parse_expr_anon_const() {
617+
Ok(length) => length,
618+
Err(e) => {
619+
e.cancel();
620+
self.restore_snapshot(snapshot);
621+
return Err(err);
622+
}
623+
};
624+
625+
if let Err(e) = self.expect(exp!(CloseBracket)) {
626+
e.cancel();
627+
self.restore_snapshot(snapshot);
628+
return Err(err);
629+
}
630+
631+
err.span_suggestion_verbose(
632+
suggestion_span,
633+
"you might have meant to use `;` as the separator",
634+
";",
635+
Applicability::MaybeIncorrect,
636+
);
637+
err.emit();
638+
Ok(TyKind::Array(elt_ty, length))
639+
}
640+
586641
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
587642
let and_span = self.prev_token.span;
588643
let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());

src/tools/tidy/src/issues.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2338,7 +2338,6 @@ ui/issues/issue-50415.rs
23382338
ui/issues/issue-50442.rs
23392339
ui/issues/issue-50471.rs
23402340
ui/issues/issue-50518.rs
2341-
ui/issues/issue-50571.rs
23422341
ui/issues/issue-50581.rs
23432342
ui/issues/issue-50582.rs
23442343
ui/issues/issue-50585.rs

src/tools/tidy/src/ui_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use ignore::Walk;
1717
const ENTRY_LIMIT: u32 = 901;
1818
// FIXME: The following limits should be reduced eventually.
1919

20-
const ISSUES_ENTRY_LIMIT: u32 = 1619;
20+
const ISSUES_ENTRY_LIMIT: u32 = 1616;
2121

2222
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
2323
"rs", // test source files

tests/ui/issues/issue-50571.fixed

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/ui/issues/issue-50571.rs

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/ui/issues/issue-50571.stderr

Lines changed: 0 additions & 15 deletions
This file was deleted.

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: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
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
6-
| |
7-
| while parsing the type for `x`
5+
| ^ expected `;` or `]`
6+
|
7+
= note: you might have meant to write a slice or array type
8+
help: you might have meant to use `;` as the separator
9+
|
10+
LL | let x: [isize ;3];
11+
| +
812

913
error: aborting due to 1 previous error
1014

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// There is a regression introduced for issue #143828
2+
//@ edition: 2015
3+
4+
#![allow(dead_code)]
5+
trait Foo {
6+
fn foo([a, b]: [i32; 2]) {}
7+
//~^ ERROR: expected `;` or `]`, found `,`
8+
//~| ERROR: patterns aren't allowed in methods without bodies
9+
}
10+
11+
fn main() {}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error: expected `;` or `]`, found `,`
2+
--> $DIR/error-pattern-issue-50571.rs:6:14
3+
|
4+
LL | fn foo([a, b]: [i32; 2]) {}
5+
| ^ expected `;` or `]`
6+
|
7+
= note: you might have meant to write a slice or array type
8+
help: you might have meant to use `;` as the separator
9+
|
10+
LL - fn foo([a, b]: [i32; 2]) {}
11+
LL + fn foo([a; b]: [i32; 2]) {}
12+
|
13+
14+
error[E0642]: patterns aren't allowed in methods without bodies
15+
--> $DIR/error-pattern-issue-50571.rs:6:12
16+
|
17+
LL | fn foo([a, b]: [i32; 2]) {}
18+
| ^^^^^^
19+
|
20+
help: give this argument a name or use an underscore to ignore it
21+
|
22+
LL - fn foo([a, b]: [i32; 2]) {}
23+
LL + fn foo(_: [i32; 2]) {}
24+
|
25+
26+
error: aborting due to 2 previous errors
27+
28+
For more information about this error, try `rustc --explain E0642`.

0 commit comments

Comments
 (0)