Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Look for available consts when typoing pattern #132582

Closed
estebank opened this issue Nov 4, 2024 · 1 comment · Fixed by #132658
Closed

Look for available consts when typoing pattern #132582

estebank opened this issue Nov 4, 2024 · 1 comment · Fixed by #132658
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@estebank
Copy link
Contributor

estebank commented Nov 4, 2024

Code

fn main() {
    let input: i32 = 42;
    
    const GOOD: i32 = 1;
    const BAD: i32 = 2;
    
    match input {
    	GOD => println!("input was 1"), //~ WARN
    	otherwise => println!("input was {otherwise}"),
    }
}

Current output

warning: unreachable pattern
 --> src/main.rs:9:6
  |
8 |         GOD => println!("input was 1"),
  |         --- matches any value
9 |         otherwise => println!("input was {otherwise}"),
  |         ^^^^^^^^^ no value can reach this
  |
  = note: `#[warn(unreachable_patterns)]` on by default

warning: unused variable: `GOD`
 --> src/main.rs:8:6
  |
8 |         GOD => println!("input was 1"),
  |         ^^^ help: if this is intentional, prefix it with an underscore: `_GOD`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: constant `GOOD` is never used
 --> src/main.rs:4:11
  |
4 |     const GOOD: i32 = 1;
  |           ^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: constant `BAD` is never used
 --> src/main.rs:5:11
  |
5 |     const BAD: i32 = 2;
  |           ^^^

warning: variable `GOD` should have a snake case name
 --> src/main.rs:8:6
  |
8 |         GOD => println!("input was 1"),
  |         ^^^ help: convert the identifier to snake case: `god`
  |
  = note: `#[warn(non_snake_case)]` on by default

Desired output

warning: unreachable pattern
 --> src/main.rs:9:6
  |
8 |         GOD => println!("input was 1"),
  |         --- matches any value
9 |         otherwise => println!("input was {otherwise}"),
  |         ^^^^^^^^^ no value can reach this
  |
  = note: `#[warn(unreachable_patterns)]` on by default
note: `GOD` looks similar to constant `GOOD`
  |
4 |     const GOOD: i32 = 1;
  |           ^^^^
help: you might have meant to pattern match on the value of the constant `GOOD`
  |
8 |         GOOD => println!("input was 1"),
  |         ~~~~

Rationale and extra context

No response

Other cases

We should also account for uppercase to lowercase changes, beyond just levenshtein distance.

Rust Version

current

Anything else?

No response

@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 4, 2024
@jieyouxu
Copy link
Member

jieyouxu commented Nov 4, 2024

Maybe cc #25207, #40476, #39371 and #121704.

estebank added a commit to estebank/rust that referenced this issue Nov 5, 2024
When writing a constant name incorrectly in a pattern, the pattern will be identified as a new binding. We look for consts in the current crate, consts that where imported in the current crate and for local `let` bindings in case someone got them confused with `const`s.

```
error: unreachable pattern
  --> $DIR/const-with-typo-in-pattern-binding.rs:30:9
   |
LL |         GOOOD => {}
   |         ----- matches any value
LL |
LL |         _ => {}
   |         ^ no value can reach this
   |
help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding
   |
LL |         GOOD => {}
   |         ~~~~
```

Fix rust-lang#132582.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 20, 2024
…eril

Point at `const` definition when used instead of a binding in a `let` statement

Modify `PatKind::InlineConstant` to be `ExpandedConstant` standing in not only for inline `const` blocks but also for `const` items. This allows us to track named `const`s used in patterns when the pattern is a single binding. When we detect that there is a refutable pattern involving a `const` that could have been a binding instead, we point at the `const` item, and suggest renaming. We do this for both `let` bindings and `match` expressions missing a catch-all arm if there's at least one single binding pattern referenced.

After:

```
error[E0005]: refutable pattern in local binding
  --> $DIR/bad-pattern.rs:19:13
   |
LL |     const PAT: u32 = 0;
   |     -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
...
LL |         let PAT = v1;
   |             ^^^ pattern `1_u32..=u32::MAX` not covered
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `u32`
help: introduce a variable instead
   |
LL |         let PAT_var = v1;
   |             ~~~~~~~
```

Before:

```
error[E0005]: refutable pattern in local binding
  --> $DIR/bad-pattern.rs:19:13
   |
LL |         let PAT = v1;
   |             ^^^
   |             |
   |             pattern `1_u32..=u32::MAX` not covered
   |             missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
   |             help: introduce a variable instead: `PAT_var`
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `u32`
```

CC rust-lang#132582.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 20, 2024
…eril

Point at `const` definition when used instead of a binding in a `let` statement

Modify `PatKind::InlineConstant` to be `ExpandedConstant` standing in not only for inline `const` blocks but also for `const` items. This allows us to track named `const`s used in patterns when the pattern is a single binding. When we detect that there is a refutable pattern involving a `const` that could have been a binding instead, we point at the `const` item, and suggest renaming. We do this for both `let` bindings and `match` expressions missing a catch-all arm if there's at least one single binding pattern referenced.

After:

```
error[E0005]: refutable pattern in local binding
  --> $DIR/bad-pattern.rs:19:13
   |
LL |     const PAT: u32 = 0;
   |     -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
...
LL |         let PAT = v1;
   |             ^^^ pattern `1_u32..=u32::MAX` not covered
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `u32`
help: introduce a variable instead
   |
LL |         let PAT_var = v1;
   |             ~~~~~~~
```

Before:

```
error[E0005]: refutable pattern in local binding
  --> $DIR/bad-pattern.rs:19:13
   |
LL |         let PAT = v1;
   |             ^^^
   |             |
   |             pattern `1_u32..=u32::MAX` not covered
   |             missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
   |             help: introduce a variable instead: `PAT_var`
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `u32`
```

CC rust-lang#132582.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Nov 21, 2024
Rollup merge of rust-lang#132708 - estebank:const-as-binding, r=Nadrieril

Point at `const` definition when used instead of a binding in a `let` statement

Modify `PatKind::InlineConstant` to be `ExpandedConstant` standing in not only for inline `const` blocks but also for `const` items. This allows us to track named `const`s used in patterns when the pattern is a single binding. When we detect that there is a refutable pattern involving a `const` that could have been a binding instead, we point at the `const` item, and suggest renaming. We do this for both `let` bindings and `match` expressions missing a catch-all arm if there's at least one single binding pattern referenced.

After:

```
error[E0005]: refutable pattern in local binding
  --> $DIR/bad-pattern.rs:19:13
   |
LL |     const PAT: u32 = 0;
   |     -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
...
LL |         let PAT = v1;
   |             ^^^ pattern `1_u32..=u32::MAX` not covered
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `u32`
help: introduce a variable instead
   |
LL |         let PAT_var = v1;
   |             ~~~~~~~
```

Before:

```
error[E0005]: refutable pattern in local binding
  --> $DIR/bad-pattern.rs:19:13
   |
LL |         let PAT = v1;
   |             ^^^
   |             |
   |             pattern `1_u32..=u32::MAX` not covered
   |             missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
   |             help: introduce a variable instead: `PAT_var`
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `u32`
```

CC rust-lang#132582.
jhpratt added a commit to jhpratt/rust that referenced this issue Nov 22, 2024
…Nadrieril

Detect const in pattern with typo

When writing a constant name incorrectly in a pattern, the pattern will be identified as a new binding. We look for consts in the current crate, consts that where imported in the current crate and for local `let` bindings in case someone got them confused with `const`s.

```
error: unreachable pattern
  --> $DIR/const-with-typo-in-pattern-binding.rs:30:9
   |
LL |         GOOOD => {}
   |         ----- matches any value
LL |
LL |         _ => {}
   |         ^ no value can reach this
   |
help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding
   |
LL |         GOOD => {}
   |         ~~~~
```

Fix rust-lang#132582.
jieyouxu added a commit to jieyouxu/rust that referenced this issue Nov 22, 2024
…Nadrieril

Detect const in pattern with typo

When writing a constant name incorrectly in a pattern, the pattern will be identified as a new binding. We look for consts in the current crate, consts that where imported in the current crate and for local `let` bindings in case someone got them confused with `const`s.

```
error: unreachable pattern
  --> $DIR/const-with-typo-in-pattern-binding.rs:30:9
   |
LL |         GOOOD => {}
   |         ----- matches any value
LL |
LL |         _ => {}
   |         ^ no value can reach this
   |
help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding
   |
LL |         GOOD => {}
   |         ~~~~
```

Fix rust-lang#132582.
compiler-errors added a commit to compiler-errors/rust that referenced this issue Nov 23, 2024
…Nadrieril

Detect const in pattern with typo

When writing a constant name incorrectly in a pattern, the pattern will be identified as a new binding. We look for consts in the current crate, consts that where imported in the current crate and for local `let` bindings in case someone got them confused with `const`s.

```
error: unreachable pattern
  --> $DIR/const-with-typo-in-pattern-binding.rs:30:9
   |
LL |         GOOOD => {}
   |         ----- matches any value
LL |
LL |         _ => {}
   |         ^ no value can reach this
   |
help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding
   |
LL |         GOOD => {}
   |         ~~~~
```

Fix rust-lang#132582.
@bors bors closed this as completed in 2487765 Nov 23, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Nov 23, 2024
Rollup merge of rust-lang#132658 - estebank:const-in-pattern-typo, r=Nadrieril

Detect const in pattern with typo

When writing a constant name incorrectly in a pattern, the pattern will be identified as a new binding. We look for consts in the current crate, consts that where imported in the current crate and for local `let` bindings in case someone got them confused with `const`s.

```
error: unreachable pattern
  --> $DIR/const-with-typo-in-pattern-binding.rs:30:9
   |
LL |         GOOOD => {}
   |         ----- matches any value
LL |
LL |         _ => {}
   |         ^ no value can reach this
   |
help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding
   |
LL |         GOOD => {}
   |         ~~~~
```

Fix rust-lang#132582.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants