Improve handling of expressions in patterns
Closes#112593.
Methodcalls' dots in patterns are silently recovered as commas (e.g. `Foo("".len())` -> `Foo("", len())`) so extra diagnostics are emitted:
```rs
struct Foo(u8, String, u8);
fn bar(foo: Foo) -> bool {
match foo {
Foo(4, "yippee".yeet(), 7) => true,
_ => false
}
}
```
```
error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
--> main.rs:5:24
|
5 | Foo(4, "yippee".yeet(), 7) => true,
| ^
| |
| expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
| help: missing `,`
error[E0531]: cannot find tuple struct or tuple variant `yeet` in this scope
--> main.rs:5:25
|
5 | Foo(4, "yippee".yeet(), 7) => true,
| ^^^^ not found in this scope
error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
--> main.rs:5:13
|
1 | struct Foo(u8, String, u8);
| -- ------ -- tuple struct has 3 fields
...
5 | Foo(4, "yippee".yeet(), 7) => true,
| ^ ^^^^^^^^ ^^^^^^ ^ expected 3 fields, found 4
error: aborting due to 3 previous errors
```
This PR checks for patterns that ends with a dot and a lowercase ident (as structs/variants should be uppercase):
```
error: expected a pattern, found a method call
--> main.rs:5:16
|
5 | Foo(4, "yippee".yeet(), 7) => true,
| ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
error: aborting due to 1 previous error
```
Also check for expressions:
```rs
fn is_idempotent(x: f32) -> bool {
match x {
x * x => true,
_ => false,
}
}
fn main() {
let mut t: [i32; 5];
let t[0] = 1;
}
```
```
error: expected a pattern, found an expression
--> main.rs:3:9
|
3 | x * x => true,
| ^^^^^ arbitrary expressions are not allowed in patterns
error: expected a pattern, found an expression
--> main.rs:10:9
|
10 | let t[0] = 1;
| ^^^^ arbitrary expressions are not allowed in patterns
```
Would be cool if the compiler could suggest adding a guard for `match`es, but I've no idea how to do it.
---
`@rustbot` label +A-diagnostics +A-parser +A-patterns +C-enhancement