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 => {}
   |            +
```
This commit is contained in:
Esteban Küber 2025-08-30 17:02:44 +00:00
parent 00f6fe1b6c
commit 3355f4bced
3 changed files with 59 additions and 20 deletions

View file

@ -1716,8 +1716,25 @@ impl<'tcx> Liveness<'_, 'tcx> {
}
}
}
// FIXME(estebank): look for consts of the same type with similar names as well, not
// just unit structs and variants.
if typo.is_none() {
for (hir_id, _, span) in &hir_ids_and_spans {
let ty = self.typeck_results.node_type(*hir_id);
// Look for consts of the same type with similar names as well, not just unit
// structs and variants.
for def_id in self.ir.tcx.hir_body_owners() {
if let DefKind::Const = self.ir.tcx.def_kind(def_id)
&& self.ir.tcx.type_of(def_id).instantiate_identity() == ty
{
typo = Some(errors::PatternTypo {
span: *span,
code: with_no_trimmed_paths!(self.ir.tcx.def_path_str(def_id)),
kind: "constant".to_string(),
item_name: self.ir.tcx.item_name(def_id).to_string(),
});
}
}
}
}
if is_assigned {
self.ir.tcx.emit_node_span_lint(
lint::builtin::UNUSED_VARIABLES,

View file

@ -5,6 +5,7 @@ enum Lol {
Bar,
}
const Bat: () = ();
const Battery: () = ();
struct Bay;
fn foo(x: (Lol, Lol)) {
@ -62,8 +63,8 @@ fn foo(x: (Lol, Lol)) {
}
fn bar(x: (Lol, Lol)) {
use Lol::*;
use Bat;
use Bay;
use ::Bat;
use ::Bay;
match &x {
(Foo, _) | (Ban, Foo) => {}
//~^ ERROR: variable `Ban` is not bound in all patterns
@ -105,6 +106,12 @@ fn baz(x: (Lol, Lol)) {
//~| HELP: if this is intentional, prefix it with an underscore
//~| HELP: you might have meant to pattern match on the similarly named
}
match () {
Batery => {}
//~^ ERROR: unused variable: `Batery`
//~| HELP: if this is intentional, prefix it with an underscore
//~| HELP: you might have meant to pattern match on the similarly named constant
}
}
fn main() {

View file

@ -1,5 +1,5 @@
error[E0408]: variable `Ban` is not bound in all patterns
--> $DIR/binding-typo-2.rs:13:9
--> $DIR/binding-typo-2.rs:14:9
|
LL | (Foo, Bar) | (Ban, Foo) => {}
| ^^^^^^^^^^ --- variable not in all patterns
@ -13,7 +13,7 @@ LL + (Foo, Bar) | (Bar, Foo) => {}
|
error[E0408]: variable `Ban` is not bound in all patterns
--> $DIR/binding-typo-2.rs:24:9
--> $DIR/binding-typo-2.rs:25:9
|
LL | (Foo, _) | (Ban, Foo) => {}
| ^^^^^^^^ --- variable not in all patterns
@ -27,7 +27,7 @@ LL + (Foo, _) | (Bar, Foo) => {}
|
error[E0408]: variable `Non` is not bound in all patterns
--> $DIR/binding-typo-2.rs:43:15
--> $DIR/binding-typo-2.rs:44:15
|
LL | Non | None => {}
| --- ^^^^ pattern doesn't bind `Non`
@ -40,7 +40,7 @@ LL | None | None => {}
| +
error[E0408]: variable `Non` is not bound in all patterns
--> $DIR/binding-typo-2.rs:53:15
--> $DIR/binding-typo-2.rs:54:15
|
LL | Non | Some(_) => {}
| --- ^^^^^^^ pattern doesn't bind `Non`
@ -54,7 +54,7 @@ LL + core::option::Option::None | Some(_) => {}
|
error[E0408]: variable `Ban` is not bound in all patterns
--> $DIR/binding-typo-2.rs:68:9
--> $DIR/binding-typo-2.rs:69:9
|
LL | (Foo, _) | (Ban, Foo) => {}
| ^^^^^^^^ --- variable not in all patterns
@ -78,7 +78,7 @@ LL + (Foo, _) | (Bat, Foo) => {}
|
error[E0408]: variable `Ban` is not bound in all patterns
--> $DIR/binding-typo-2.rs:85:9
--> $DIR/binding-typo-2.rs:86:9
|
LL | (Foo, _) | (Ban, Foo) => {}
| ^^^^^^^^ --- variable not in all patterns
@ -97,7 +97,7 @@ LL + (Foo, _) | (Bat, Foo) => {}
|
error: variable `Ban` is assigned to, but never used
--> $DIR/binding-typo-2.rs:13:23
--> $DIR/binding-typo-2.rs:14:23
|
LL | (Foo, Bar) | (Ban, Foo) => {}
| ^^^
@ -115,7 +115,7 @@ LL + (Foo, Bar) | (Lol::Bar, Foo) => {}
|
error: variable `Ban` is assigned to, but never used
--> $DIR/binding-typo-2.rs:24:21
--> $DIR/binding-typo-2.rs:25:21
|
LL | (Foo, _) | (Ban, Foo) => {}
| ^^^
@ -128,7 +128,7 @@ LL + (Foo, _) | (Lol::Bar, Foo) => {}
|
error: unused variable: `Non`
--> $DIR/binding-typo-2.rs:36:9
--> $DIR/binding-typo-2.rs:37:9
|
LL | Non => {}
| ^^^
@ -144,7 +144,7 @@ LL + std::prelude::v1::None => {}
|
error: unused variable: `Non`
--> $DIR/binding-typo-2.rs:43:9
--> $DIR/binding-typo-2.rs:44:9
|
LL | Non | None => {}
| ^^^
@ -160,7 +160,7 @@ LL + std::prelude::v1::None | None => {}
|
error: unused variable: `Non`
--> $DIR/binding-typo-2.rs:53:9
--> $DIR/binding-typo-2.rs:54:9
|
LL | Non | Some(_) => {}
| ^^^
@ -176,7 +176,7 @@ LL + std::prelude::v1::None | Some(_) => {}
|
error: variable `Ban` is assigned to, but never used
--> $DIR/binding-typo-2.rs:68:21
--> $DIR/binding-typo-2.rs:69:21
|
LL | (Foo, _) | (Ban, Foo) => {}
| ^^^
@ -189,7 +189,7 @@ LL + (Foo, _) | (Lol::Bar, Foo) => {}
|
error: variable `Ban` is assigned to, but never used
--> $DIR/binding-typo-2.rs:85:21
--> $DIR/binding-typo-2.rs:86:21
|
LL | (Foo, _) | (Ban, Foo) => {}
| ^^^
@ -202,7 +202,7 @@ LL + (Foo, _) | (Lol::Bar, Foo) => {}
|
error: unused variable: `Ban`
--> $DIR/binding-typo-2.rs:97:10
--> $DIR/binding-typo-2.rs:98:10
|
LL | (Ban, _) => {}
| ^^^
@ -218,7 +218,7 @@ LL + (Lol::Bar, _) => {}
|
error: unused variable: `Ban`
--> $DIR/binding-typo-2.rs:103:9
--> $DIR/binding-typo-2.rs:104:9
|
LL | Ban => {}
| ^^^
@ -233,6 +233,21 @@ LL - Ban => {}
LL + Bay => {}
|
error: aborting due to 15 previous errors
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 => {}
| +
error: aborting due to 16 previous errors
For more information about this error, try `rustc --explain E0408`.