Skip to content

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Aug 24, 2025

When encountering an or-pattern with a binding not available in all patterns, look for consts and unit struct/variants that have similar names as the binding to detect typos.

error[E0408]: variable `Ban` is not bound in all patterns
  --> $DIR/binding-typo.rs:22:9
   |
LL |         (Foo, _) | (Ban, Foo) => {}
   |         ^^^^^^^^    --- variable not in all patterns
   |         |
   |         pattern doesn't bind `Ban`
   |
help: you might have meant to use the similarly named unit variant `Bar`
   |
LL -         (Foo, _) | (Ban, Foo) => {}
LL +         (Foo, _) | (Bar, Foo) => {}
   |

For items that are not in the immedate scope, suggest the full path for them:

error[E0408]: variable `Non` is not bound in all patterns
  --> $DIR/binding-typo-2.rs:51:16
   |
LL |         (Non | Some(_))=> {}
   |          ---   ^^^^^^^ pattern doesn't bind `Non`
   |          |
   |          variable not in all patterns
   |
help: you might have meant to use the similarly named unit variant `None`
   |
LL -         (Non | Some(_))=> {}
LL +         (core::option::Option::None | Some(_))=> {}
   |

When encountering a typo in a pattern that gets interpreted as an unused binding, look for unit struct/variant of the same type as the binding:

error: unused variable: `Non`
  --> $DIR/binding-typo-2.rs:36:9
   |
LL |         Non => {}
   |         ^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Non => {}
   |         +
help: you might have meant to pattern match on the similarly named variant `None`
   |
LL -         Non => {}
LL +         std::prelude::v1::None => {}
   |

Suggest constant on unused binding in a pattern

error: unused variable: `Batery`
  --> $DIR/binding-typo-2.rs:110:9
   |
LL |         Batery => {}
   |         ^^^^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Batery => {}
   |         +
help: you might have meant to pattern match on the similarly named constant `Battery`
   |
LL |         Battery => {}
   |            +

Fix #51976.

@rustbot
Copy link
Collaborator

rustbot commented Aug 24, 2025

r? @fee1-dead

rustbot has assigned @fee1-dead.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 24, 2025
@rust-log-analyzer

This comment has been minimized.

```
error[E0408]: variable `Ban` is not bound in all patterns
 --> f12.rs:9:9
  |
9 |         (Foo,Bar)|(Ban,Foo) => {}
  |         ^^^^^^^^^  --- variable not in all patterns
  |         |
  |         pattern doesn't bind `Ban`
  |
help: you might have meant to use the similarly named previously used binding `Bar`
  |
9 -         (Foo,Bar)|(Ban,Foo) => {}
9 +         (Foo,Bar)|(Bar,Foo) => {}
  |
```
@fee1-dead
Copy link
Member

Hmmm. I'm not entirely sure whether this actually fixes the original issue as the original issue is about a variant in scope. I would like to see the original issue in a test.

…ts/variants for suggestions

When encountering an or-pattern with a binding not available in all patterns, look for consts and unit struct/variants that have similar names as the binding to detect typos.

```
error[E0408]: variable `Ban` is not bound in all patterns
  --> $DIR/binding-typo.rs:22:9
   |
LL |         (Foo, _) | (Ban, Foo) => {}
   |         ^^^^^^^^    --- variable not in all patterns
   |         |
   |         pattern doesn't bind `Ban`
   |
help: you might have meant to use the similarly named unit variant `Bar`
   |
LL -         (Foo, _) | (Ban, Foo) => {}
LL +         (Foo, _) | (Bar, Foo) => {}
   |
```

For items that are not in the immedate scope, suggest the full path for them:

```
error[E0408]: variable `Non` is not bound in all patterns
  --> $DIR/binding-typo-2.rs:51:16
   |
LL |         (Non | Some(_))=> {}
   |          ---   ^^^^^^^ pattern doesn't bind `Non`
   |          |
   |          variable not in all patterns
   |
help: you might have meant to use the similarly named unit variant `None`
   |
LL -         (Non | Some(_))=> {}
LL +         (core::option::Option::None | Some(_))=> {}
   |
```
…r name

When encountering a typo in a pattern that gets interpreted as an unused binding, look for unit struct/variant of the same type as the binding:

```
error: unused variable: `Non`
  --> $DIR/binding-typo-2.rs:36:9
   |
LL |         Non => {}
   |         ^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Non => {}
   |         +
help: you might have meant to pattern match on the similarly named variant `None`
   |
LL -         Non => {}
LL +         std::prelude::v1::None => {}
   |
```
```
error: unused variable: `Batery`
  --> $DIR/binding-typo-2.rs:110:9
   |
LL |         Batery => {}
   |         ^^^^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Batery => {}
   |         +
help: you might have meant to pattern match on the similarly named constant `Battery`
   |
LL |         Battery => {}
   |            +
```
@estebank estebank changed the title On binding not present in all patterns, suggest potential typo On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const Aug 30, 2025
@@ -1,5 +1,5 @@
//@ run-rustfix
#![deny(unused_assignments, unused_variables)]
#![deny(unused_assignments)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed because that lint now emits:

error: variable `object` is assigned to, but never used
  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:23
   |
LL | fn change_object2(mut object: &Object) {
   |                       ^^^^^^
   |
   = note: consider using `_object` instead
note: the lint level is defined here
  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:29
   |
LL | #![deny(unused_assignments, unused_variables)]
   |                             ^^^^^^^^^^^^^^^^
help: you might have meant to pattern match on the similarly named struct `Object` (notice the capitalization)
   |
LL - fn change_object2(mut object: &Object) {
LL + fn change_object2(mut Object: &Object) {
   |

which would make this test no longer run-rustfixable.

fn foo(x: (Lol, Lol)) {
use Lol::*;
match &x {
(Foo, Bar) | (Ban, Foo) => {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the original case in the ticket, where it was a simple typo and the binding was available in the other or-pattern.

_ => {}
}
match &x {
(Foo, _) | (Ban, Foo) => {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the case where the typo'd variant is not even present in the other or-pattern.

}
match Some(42) {
Some(_) => {}
Non => {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test when an or-pattern isn't involved.

@fee1-dead
Copy link
Member

Sorry, I lack capacity at the moment and have to reroll.

r? compiler

@rustbot rustbot assigned jackh726 and unassigned fee1-dead Sep 1, 2025
@jackh726
Copy link
Member

jackh726 commented Sep 3, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Sep 3, 2025

📌 Commit 86085b4 has been approved by jackh726

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 3, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Sep 4, 2025
On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const

When encountering an or-pattern with a binding not available in all patterns, look for consts and unit struct/variants that have similar names as the binding to detect typos.

```
error[E0408]: variable `Ban` is not bound in all patterns
  --> $DIR/binding-typo.rs:22:9
   |
LL |         (Foo, _) | (Ban, Foo) => {}
   |         ^^^^^^^^    --- variable not in all patterns
   |         |
   |         pattern doesn't bind `Ban`
   |
help: you might have meant to use the similarly named unit variant `Bar`
   |
LL -         (Foo, _) | (Ban, Foo) => {}
LL +         (Foo, _) | (Bar, Foo) => {}
   |
```

For items that are not in the immedate scope, suggest the full path for them:

```
error[E0408]: variable `Non` is not bound in all patterns
  --> $DIR/binding-typo-2.rs:51:16
   |
LL |         (Non | Some(_))=> {}
   |          ---   ^^^^^^^ pattern doesn't bind `Non`
   |          |
   |          variable not in all patterns
   |
help: you might have meant to use the similarly named unit variant `None`
   |
LL -         (Non | Some(_))=> {}
LL +         (core::option::Option::None | Some(_))=> {}
   |
```

When encountering a typo in a pattern that gets interpreted as an unused binding, look for unit struct/variant of the same type as the binding:

```
error: unused variable: `Non`
  --> $DIR/binding-typo-2.rs:36:9
   |
LL |         Non => {}
   |         ^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Non => {}
   |         +
help: you might have meant to pattern match on the similarly named variant `None`
   |
LL -         Non => {}
LL +         std::prelude::v1::None => {}
   |
```

 Suggest constant on unused binding in a pattern

```
error: unused variable: `Batery`
  --> $DIR/binding-typo-2.rs:110:9
   |
LL |         Batery => {}
   |         ^^^^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Batery => {}
   |         +
help: you might have meant to pattern match on the similarly named constant `Battery`
   |
LL |         Battery => {}
   |            +
```

Fix rust-lang#51976.
bors added a commit that referenced this pull request Sep 4, 2025
Rollup of 24 pull requests

Successful merges:

 - #140459 (Add `read_buf` equivalents for positioned reads)
 - #143725 (core: add Peekable::next_if_map)
 - #145209 (Stabilize `path_add_extension`)
 - #145342 (fix drop scope for `super let` bindings within `if let`)
 - #145750 (raw_vec.rs: Remove superfluous fn alloc_guard)
 - #145827 (On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const)
 - #145932 (Allow `inline(always)` with a target feature behind a unstable feature `target_feature_inline_always`.)
 - #145962 (Ensure we emit an allocator shim when only some crate types need one)
 - #145963 (Add LSX accelerated implementation for source file analysis)
 - #146054 (add `#[must_use]` to `array::repeat`)
 - #146090 (Derive `PartialEq` for `InvisibleOrigin`)
 - #146112 (don't uppercase error messages)
 - #146120 (Correct typo in `rustc_errors` comment)
 - #146124 (Test `rustc-dev` in `distcheck`)
 - #146127 (Rename `ToolRustc` to `ToolRustcPrivate`)
 - #146131 (rustdoc-search: add test case for indexing every item type)
 - #146134 (llvm: nvptx: Layout update to match LLVM)
 - #146136 (docs(std): add missing closing code block fences in doc comments)
 - #146137 (Disallow frontmatter in `--cfg` and `--check-cfg` arguments)
 - #146140 (compiletest: cygwin follows windows in using PATH for dynamic libraries)
 - #146150 (fix(rustdoc): match rustc `--emit` precedence )
 - #146155 (Make bootstrap self test parallel)
 - #146161 ([rustdoc] Uncomment code to add scraped rustdoc examples in loaded paths)
 - #146172 (triagebot: configure some pings when certain attributes are used)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 3a6ae11 into rust-lang:master Sep 4, 2025
10 checks passed
@rustbot rustbot added this to the 1.91.0 milestone Sep 4, 2025
rust-timer added a commit that referenced this pull request Sep 4, 2025
Rollup merge of #145827 - estebank:issue-51976, r=jackh726

On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const

When encountering an or-pattern with a binding not available in all patterns, look for consts and unit struct/variants that have similar names as the binding to detect typos.

```
error[E0408]: variable `Ban` is not bound in all patterns
  --> $DIR/binding-typo.rs:22:9
   |
LL |         (Foo, _) | (Ban, Foo) => {}
   |         ^^^^^^^^    --- variable not in all patterns
   |         |
   |         pattern doesn't bind `Ban`
   |
help: you might have meant to use the similarly named unit variant `Bar`
   |
LL -         (Foo, _) | (Ban, Foo) => {}
LL +         (Foo, _) | (Bar, Foo) => {}
   |
```

For items that are not in the immedate scope, suggest the full path for them:

```
error[E0408]: variable `Non` is not bound in all patterns
  --> $DIR/binding-typo-2.rs:51:16
   |
LL |         (Non | Some(_))=> {}
   |          ---   ^^^^^^^ pattern doesn't bind `Non`
   |          |
   |          variable not in all patterns
   |
help: you might have meant to use the similarly named unit variant `None`
   |
LL -         (Non | Some(_))=> {}
LL +         (core::option::Option::None | Some(_))=> {}
   |
```

When encountering a typo in a pattern that gets interpreted as an unused binding, look for unit struct/variant of the same type as the binding:

```
error: unused variable: `Non`
  --> $DIR/binding-typo-2.rs:36:9
   |
LL |         Non => {}
   |         ^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Non => {}
   |         +
help: you might have meant to pattern match on the similarly named variant `None`
   |
LL -         Non => {}
LL +         std::prelude::v1::None => {}
   |
```

 Suggest constant on unused binding in a pattern

```
error: unused variable: `Batery`
  --> $DIR/binding-typo-2.rs:110:9
   |
LL |         Batery => {}
   |         ^^^^^^
   |
help: if this is intentional, prefix it with an underscore
   |
LL |         _Batery => {}
   |         +
help: you might have meant to pattern match on the similarly named constant `Battery`
   |
LL |         Battery => {}
   |            +
```

Fix #51976.
@Zalathar
Copy link
Contributor

Zalathar commented Sep 4, 2025

Perf results from rollup (regressions and improvements):

github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Sep 5, 2025
Rollup of 24 pull requests

Successful merges:

 - rust-lang/rust#140459 (Add `read_buf` equivalents for positioned reads)
 - rust-lang/rust#143725 (core: add Peekable::next_if_map)
 - rust-lang/rust#145209 (Stabilize `path_add_extension`)
 - rust-lang/rust#145342 (fix drop scope for `super let` bindings within `if let`)
 - rust-lang/rust#145750 (raw_vec.rs: Remove superfluous fn alloc_guard)
 - rust-lang/rust#145827 (On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const)
 - rust-lang/rust#145932 (Allow `inline(always)` with a target feature behind a unstable feature `target_feature_inline_always`.)
 - rust-lang/rust#145962 (Ensure we emit an allocator shim when only some crate types need one)
 - rust-lang/rust#145963 (Add LSX accelerated implementation for source file analysis)
 - rust-lang/rust#146054 (add `#[must_use]` to `array::repeat`)
 - rust-lang/rust#146090 (Derive `PartialEq` for `InvisibleOrigin`)
 - rust-lang/rust#146112 (don't uppercase error messages)
 - rust-lang/rust#146120 (Correct typo in `rustc_errors` comment)
 - rust-lang/rust#146124 (Test `rustc-dev` in `distcheck`)
 - rust-lang/rust#146127 (Rename `ToolRustc` to `ToolRustcPrivate`)
 - rust-lang/rust#146131 (rustdoc-search: add test case for indexing every item type)
 - rust-lang/rust#146134 (llvm: nvptx: Layout update to match LLVM)
 - rust-lang/rust#146136 (docs(std): add missing closing code block fences in doc comments)
 - rust-lang/rust#146137 (Disallow frontmatter in `--cfg` and `--check-cfg` arguments)
 - rust-lang/rust#146140 (compiletest: cygwin follows windows in using PATH for dynamic libraries)
 - rust-lang/rust#146150 (fix(rustdoc): match rustc `--emit` precedence )
 - rust-lang/rust#146155 (Make bootstrap self test parallel)
 - rust-lang/rust#146161 ([rustdoc] Uncomment code to add scraped rustdoc examples in loaded paths)
 - rust-lang/rust#146172 (triagebot: configure some pings when certain attributes are used)

r? `@ghost`
`@rustbot` modify labels: rollup
github-actions bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Sep 8, 2025
Rollup of 24 pull requests

Successful merges:

 - rust-lang/rust#140459 (Add `read_buf` equivalents for positioned reads)
 - rust-lang/rust#143725 (core: add Peekable::next_if_map)
 - rust-lang/rust#145209 (Stabilize `path_add_extension`)
 - rust-lang/rust#145342 (fix drop scope for `super let` bindings within `if let`)
 - rust-lang/rust#145750 (raw_vec.rs: Remove superfluous fn alloc_guard)
 - rust-lang/rust#145827 (On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const)
 - rust-lang/rust#145932 (Allow `inline(always)` with a target feature behind a unstable feature `target_feature_inline_always`.)
 - rust-lang/rust#145962 (Ensure we emit an allocator shim when only some crate types need one)
 - rust-lang/rust#145963 (Add LSX accelerated implementation for source file analysis)
 - rust-lang/rust#146054 (add `#[must_use]` to `array::repeat`)
 - rust-lang/rust#146090 (Derive `PartialEq` for `InvisibleOrigin`)
 - rust-lang/rust#146112 (don't uppercase error messages)
 - rust-lang/rust#146120 (Correct typo in `rustc_errors` comment)
 - rust-lang/rust#146124 (Test `rustc-dev` in `distcheck`)
 - rust-lang/rust#146127 (Rename `ToolRustc` to `ToolRustcPrivate`)
 - rust-lang/rust#146131 (rustdoc-search: add test case for indexing every item type)
 - rust-lang/rust#146134 (llvm: nvptx: Layout update to match LLVM)
 - rust-lang/rust#146136 (docs(std): add missing closing code block fences in doc comments)
 - rust-lang/rust#146137 (Disallow frontmatter in `--cfg` and `--check-cfg` arguments)
 - rust-lang/rust#146140 (compiletest: cygwin follows windows in using PATH for dynamic libraries)
 - rust-lang/rust#146150 (fix(rustdoc): match rustc `--emit` precedence )
 - rust-lang/rust#146155 (Make bootstrap self test parallel)
 - rust-lang/rust#146161 ([rustdoc] Uncomment code to add scraped rustdoc examples in loaded paths)
 - rust-lang/rust#146172 (triagebot: configure some pings when certain attributes are used)

r? `@ghost`
`@rustbot` modify labels: rollup
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Sep 9, 2025
Rollup of 24 pull requests

Successful merges:

 - rust-lang#140459 (Add `read_buf` equivalents for positioned reads)
 - rust-lang#143725 (core: add Peekable::next_if_map)
 - rust-lang#145209 (Stabilize `path_add_extension`)
 - rust-lang#145342 (fix drop scope for `super let` bindings within `if let`)
 - rust-lang#145750 (raw_vec.rs: Remove superfluous fn alloc_guard)
 - rust-lang#145827 (On unused binding or binding not present in all patterns, suggest potential typo of unit struct/variant or const)
 - rust-lang#145932 (Allow `inline(always)` with a target feature behind a unstable feature `target_feature_inline_always`.)
 - rust-lang#145962 (Ensure we emit an allocator shim when only some crate types need one)
 - rust-lang#145963 (Add LSX accelerated implementation for source file analysis)
 - rust-lang#146054 (add `#[must_use]` to `array::repeat`)
 - rust-lang#146090 (Derive `PartialEq` for `InvisibleOrigin`)
 - rust-lang#146112 (don't uppercase error messages)
 - rust-lang#146120 (Correct typo in `rustc_errors` comment)
 - rust-lang#146124 (Test `rustc-dev` in `distcheck`)
 - rust-lang#146127 (Rename `ToolRustc` to `ToolRustcPrivate`)
 - rust-lang#146131 (rustdoc-search: add test case for indexing every item type)
 - rust-lang#146134 (llvm: nvptx: Layout update to match LLVM)
 - rust-lang#146136 (docs(std): add missing closing code block fences in doc comments)
 - rust-lang#146137 (Disallow frontmatter in `--cfg` and `--check-cfg` arguments)
 - rust-lang#146140 (compiletest: cygwin follows windows in using PATH for dynamic libraries)
 - rust-lang#146150 (fix(rustdoc): match rustc `--emit` precedence )
 - rust-lang#146155 (Make bootstrap self test parallel)
 - rust-lang#146161 ([rustdoc] Uncomment code to add scraped rustdoc examples in loaded paths)
 - rust-lang#146172 (triagebot: configure some pings when certain attributes are used)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Diagnostic error[E0408]: variable ... is not bound in all patterns should be more helpful with typos.
7 participants