Recover and suggest use ; to construct array type
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
parent
1cac8cbde9
commit
ed88af2163
14 changed files with 183 additions and 87 deletions
|
|
@ -575,14 +575,69 @@ impl<'a> Parser<'a> {
|
|||
self.expect(exp!(CloseBracket))?;
|
||||
}
|
||||
TyKind::Array(elt_ty, length)
|
||||
} else {
|
||||
self.expect(exp!(CloseBracket))?;
|
||||
} else if self.eat(exp!(CloseBracket)) {
|
||||
TyKind::Slice(elt_ty)
|
||||
} else {
|
||||
self.maybe_recover_array_ty_without_semi(elt_ty)?
|
||||
};
|
||||
|
||||
Ok(ty)
|
||||
}
|
||||
|
||||
/// Recover from malformed array type syntax.
|
||||
///
|
||||
/// This method attempts to recover from cases like:
|
||||
/// - `[u8, 5]` → suggests using `;`, return a Array type
|
||||
/// - `[u8 5]` → suggests using `;`, return a Array type
|
||||
/// Consider to add more cases in the future.
|
||||
fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: P<Ty>) -> PResult<'a, TyKind> {
|
||||
let span = self.token.span;
|
||||
let token_descr = super::token_descr(&self.token);
|
||||
let mut err =
|
||||
self.dcx().struct_span_err(span, format!("expected `;` or `]`, found {}", token_descr));
|
||||
err.span_label(span, "expected `;` or `]`");
|
||||
err.note("you might have meant to write a slice or array type");
|
||||
|
||||
// If we cannot recover, return the error immediately.
|
||||
if !self.may_recover() {
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
|
||||
let suggestion_span = if self.eat(exp!(Comma)) || self.eat(exp!(Star)) {
|
||||
// Consume common erroneous separators.
|
||||
self.prev_token.span
|
||||
} else {
|
||||
self.token.span.shrink_to_lo()
|
||||
};
|
||||
|
||||
// we first try to parse pattern like `[u8 5]`
|
||||
let length = match self.parse_expr_anon_const() {
|
||||
Ok(length) => length,
|
||||
Err(e) => {
|
||||
e.cancel();
|
||||
self.restore_snapshot(snapshot);
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = self.expect(exp!(CloseBracket)) {
|
||||
e.cancel();
|
||||
self.restore_snapshot(snapshot);
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
suggestion_span,
|
||||
"you might have meant to use `;` as the separator",
|
||||
";",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.emit();
|
||||
Ok(TyKind::Array(elt_ty, length))
|
||||
}
|
||||
|
||||
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
|
||||
let and_span = self.prev_token.span;
|
||||
let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
|
||||
|
|
|
|||
|
|
@ -2338,7 +2338,6 @@ ui/issues/issue-50415.rs
|
|||
ui/issues/issue-50442.rs
|
||||
ui/issues/issue-50471.rs
|
||||
ui/issues/issue-50518.rs
|
||||
ui/issues/issue-50571.rs
|
||||
ui/issues/issue-50581.rs
|
||||
ui/issues/issue-50582.rs
|
||||
ui/issues/issue-50585.rs
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use ignore::Walk;
|
|||
const ENTRY_LIMIT: u32 = 901;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
|
||||
const ISSUES_ENTRY_LIMIT: u32 = 1619;
|
||||
const ISSUES_ENTRY_LIMIT: u32 = 1616;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
//@ edition: 2015
|
||||
//@ run-rustfix
|
||||
|
||||
#![allow(dead_code)]
|
||||
trait Foo {
|
||||
fn foo(_: [i32; 2]) {}
|
||||
//~^ ERROR: patterns aren't allowed in methods without bodies
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
//@ edition: 2015
|
||||
//@ run-rustfix
|
||||
|
||||
#![allow(dead_code)]
|
||||
trait Foo {
|
||||
fn foo([a, b]: [i32; 2]) {}
|
||||
//~^ ERROR: patterns aren't allowed in methods without bodies
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
error[E0642]: patterns aren't allowed in methods without bodies
|
||||
--> $DIR/issue-50571.rs:6:12
|
||||
|
|
||||
LL | fn foo([a, b]: [i32; 2]) {}
|
||||
| ^^^^^^
|
||||
|
|
||||
help: give this argument a name or use an underscore to ignore it
|
||||
|
|
||||
LL - fn foo([a, b]: [i32; 2]) {}
|
||||
LL + fn foo(_: [i32; 2]) {}
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0642`.
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
fn main() {
|
||||
let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
|
||||
let x: [isize 3]; //~ ERROR expected `;` or `]`, found `3`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
|
||||
error: expected `;` or `]`, found `3`
|
||||
--> $DIR/better-expected.rs:2:19
|
||||
|
|
||||
LL | let x: [isize 3];
|
||||
| - ^ expected one of 7 possible tokens
|
||||
| |
|
||||
| while parsing the type for `x`
|
||||
| ^ expected `;` or `]`
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
help: you might have meant to use `;` as the separator
|
||||
|
|
||||
LL | let x: [isize ;3];
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
11
tests/ui/parser/issues/error-pattern-issue-50571.rs
Normal file
11
tests/ui/parser/issues/error-pattern-issue-50571.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// There is a regression introduced for issue #143828
|
||||
//@ edition: 2015
|
||||
|
||||
#![allow(dead_code)]
|
||||
trait Foo {
|
||||
fn foo([a, b]: [i32; 2]) {}
|
||||
//~^ ERROR: expected `;` or `]`, found `,`
|
||||
//~| ERROR: patterns aren't allowed in methods without bodies
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
28
tests/ui/parser/issues/error-pattern-issue-50571.stderr
Normal file
28
tests/ui/parser/issues/error-pattern-issue-50571.stderr
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
error: expected `;` or `]`, found `,`
|
||||
--> $DIR/error-pattern-issue-50571.rs:6:14
|
||||
|
|
||||
LL | fn foo([a, b]: [i32; 2]) {}
|
||||
| ^ expected `;` or `]`
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
help: you might have meant to use `;` as the separator
|
||||
|
|
||||
LL - fn foo([a, b]: [i32; 2]) {}
|
||||
LL + fn foo([a; b]: [i32; 2]) {}
|
||||
|
|
||||
|
||||
error[E0642]: patterns aren't allowed in methods without bodies
|
||||
--> $DIR/error-pattern-issue-50571.rs:6:12
|
||||
|
|
||||
LL | fn foo([a, b]: [i32; 2]) {}
|
||||
| ^^^^^^
|
||||
|
|
||||
help: give this argument a name or use an underscore to ignore it
|
||||
|
|
||||
LL - fn foo([a, b]: [i32; 2]) {}
|
||||
LL + fn foo(_: [i32; 2]) {}
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0642`.
|
||||
|
|
@ -5,14 +5,13 @@
|
|||
fn main() {
|
||||
let x = 5;
|
||||
let b: [i32, 5];
|
||||
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
|
||||
//~| ERROR expected value, found builtin type `i32` [E0423]
|
||||
//~^ ERROR expected `;` or `]`, found `,`
|
||||
let a: [i32, ];
|
||||
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
|
||||
//~^ ERROR expected `;` or `]`, found `,`
|
||||
//~| ERROR expected value, found builtin type `i32` [E0423]
|
||||
let c: [i32, x];
|
||||
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
|
||||
//~| ERROR expected value, found builtin type `i32` [E0423]
|
||||
//~^ ERROR expected `;` or `]`, found `,`
|
||||
//~| ERROR attempt to use a non-constant value in a constant [E0435]
|
||||
let e: [i32 5];
|
||||
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `5`
|
||||
//~^ ERROR expected `;` or `]`, found `5`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,71 @@
|
|||
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
|
||||
error: expected `;` or `]`, found `,`
|
||||
--> $DIR/array-type-no-semi.rs:7:16
|
||||
|
|
||||
LL | let b: [i32, 5];
|
||||
| - ^ expected one of 7 possible tokens
|
||||
| |
|
||||
| while parsing the type for `b`
|
||||
| help: use `=` if you meant to assign
|
||||
| ^ expected `;` or `]`
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
help: you might have meant to use `;` as the separator
|
||||
|
|
||||
LL - let b: [i32, 5];
|
||||
LL + let b: [i32; 5];
|
||||
|
|
||||
|
||||
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
|
||||
--> $DIR/array-type-no-semi.rs:10:16
|
||||
error: expected `;` or `]`, found `,`
|
||||
--> $DIR/array-type-no-semi.rs:9:16
|
||||
|
|
||||
LL | let a: [i32, ];
|
||||
| - ^ expected one of 7 possible tokens
|
||||
| - ^ expected `;` or `]`
|
||||
| |
|
||||
| while parsing the type for `a`
|
||||
| help: use `=` if you meant to assign
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
|
||||
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `,`
|
||||
--> $DIR/array-type-no-semi.rs:13:16
|
||||
error: expected `;` or `]`, found `,`
|
||||
--> $DIR/array-type-no-semi.rs:12:16
|
||||
|
|
||||
LL | let c: [i32, x];
|
||||
| - ^ expected one of 7 possible tokens
|
||||
| |
|
||||
| while parsing the type for `c`
|
||||
| help: use `=` if you meant to assign
|
||||
| ^ expected `;` or `]`
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
help: you might have meant to use `;` as the separator
|
||||
|
|
||||
LL - let c: [i32, x];
|
||||
LL + let c: [i32; x];
|
||||
|
|
||||
|
||||
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `5`
|
||||
--> $DIR/array-type-no-semi.rs:16:17
|
||||
error: expected `;` or `]`, found `5`
|
||||
--> $DIR/array-type-no-semi.rs:15:17
|
||||
|
|
||||
LL | let e: [i32 5];
|
||||
| - ^ expected one of 7 possible tokens
|
||||
| |
|
||||
| while parsing the type for `e`
|
||||
|
||||
error[E0423]: expected value, found builtin type `i32`
|
||||
--> $DIR/array-type-no-semi.rs:7:13
|
||||
| ^ expected `;` or `]`
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
help: you might have meant to use `;` as the separator
|
||||
|
|
||||
LL | let e: [i32 ;5];
|
||||
| +
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/array-type-no-semi.rs:12:18
|
||||
|
|
||||
LL | let c: [i32, x];
|
||||
| ^ non-constant value
|
||||
|
|
||||
help: consider using `const` instead of `let`
|
||||
|
|
||||
LL - let x = 5;
|
||||
LL + const x: /* Type */ = 5;
|
||||
|
|
||||
LL | let b: [i32, 5];
|
||||
| ^^^ not a value
|
||||
|
||||
error[E0423]: expected value, found builtin type `i32`
|
||||
--> $DIR/array-type-no-semi.rs:10:13
|
||||
--> $DIR/array-type-no-semi.rs:9:13
|
||||
|
|
||||
LL | let a: [i32, ];
|
||||
| ^^^ not a value
|
||||
|
||||
error[E0423]: expected value, found builtin type `i32`
|
||||
--> $DIR/array-type-no-semi.rs:13:13
|
||||
|
|
||||
LL | let c: [i32, x];
|
||||
| ^^^ not a value
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0423`.
|
||||
Some errors have detailed explanations: E0423, E0435.
|
||||
For more information about an error, try `rustc --explain E0423`.
|
||||
|
|
|
|||
|
|
@ -1 +1,6 @@
|
|||
type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
|
||||
type v = [isize * 3];
|
||||
//~^ ERROR expected `;` or `]`, found `*`
|
||||
//~| WARN type `v` should have an upper camel case name [non_camel_case_types]
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,23 @@
|
|||
error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
|
||||
error: expected `;` or `]`, found `*`
|
||||
--> $DIR/removed-syntax-fixed-vec.rs:1:17
|
||||
|
|
||||
LL | type v = [isize * 3];
|
||||
| ^ expected one of 7 possible tokens
|
||||
| ^ expected `;` or `]`
|
||||
|
|
||||
= note: you might have meant to write a slice or array type
|
||||
help: you might have meant to use `;` as the separator
|
||||
|
|
||||
LL - type v = [isize * 3];
|
||||
LL + type v = [isize ; 3];
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
warning: type `v` should have an upper camel case name
|
||||
--> $DIR/removed-syntax-fixed-vec.rs:1:6
|
||||
|
|
||||
LL | type v = [isize * 3];
|
||||
| ^ help: convert the identifier to upper camel case (notice the capitalization): `V`
|
||||
|
|
||||
= note: `#[warn(non_camel_case_types)]` on by default
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue