diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2025-08-30 17:44:23 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2025-08-30 17:44:23 +0000 |
| commit | 86085b4f65fae0ebc456202584e7e04b58a871f3 (patch) | |
| tree | 85df0b601b3ade0ffeed6064744294ce83c36bb1 | |
| parent | 3355f4bced511aba46c5a92ea82241b6713331ba (diff) | |
| download | rust-86085b4f65fae0ebc456202584e7e04b58a871f3.tar.gz rust-86085b4f65fae0ebc456202584e7e04b58a871f3.zip | |
Avoid unnecessary suggestion in or-pattern
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 42 | ||||
| -rw-r--r-- | tests/ui/or-patterns/binding-typo-2.rs | 2 | ||||
| -rw-r--r-- | tests/ui/or-patterns/binding-typo-2.stderr | 7 | ||||
| -rw-r--r-- | tests/ui/or-patterns/mismatched-bindings-async-fn.stderr | 24 | ||||
| -rw-r--r-- | tests/ui/or-patterns/nested-undelimited-precedence.stderr | 6 | ||||
| -rw-r--r-- | tests/ui/resolve/resolve-inconsistent-names.rs | 2 | ||||
| -rw-r--r-- | tests/ui/resolve/resolve-inconsistent-names.stderr | 26 |
7 files changed, 36 insertions, 73 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index beb882a325f..b7042045242 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -678,26 +678,32 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for sp in &origin_sp { err.subdiagnostic(errors::VariableNotInAllPatterns { span: *sp }); } - let mut target_visitor = BindingVisitor::default(); - for pat in &target { - target_visitor.visit_pat(pat); - } - target_visitor.identifiers.sort(); - target_visitor.identifiers.dedup(); - let mut origin_visitor = BindingVisitor::default(); - for (_, pat) in &origin { - origin_visitor.visit_pat(pat); - } - origin_visitor.identifiers.sort(); - origin_visitor.identifiers.dedup(); - // Find if the binding could have been a typo let mut suggested_typo = false; - if let Some(typo) = - find_best_match_for_name(&target_visitor.identifiers, name.name, None) - && !origin_visitor.identifiers.contains(&typo) + if !target.iter().all(|pat| matches!(pat.kind, ast::PatKind::Ident(..))) + && !origin.iter().all(|(_, pat)| matches!(pat.kind, ast::PatKind::Ident(..))) { - err.subdiagnostic(errors::PatternBindingTypo { spans: origin_sp, typo }); - suggested_typo = true; + // The check above is so that when we encounter `match foo { (a | b) => {} }`, + // we don't suggest `(a | a) => {}`, which would never be what the user wants. + let mut target_visitor = BindingVisitor::default(); + for pat in &target { + target_visitor.visit_pat(pat); + } + target_visitor.identifiers.sort(); + target_visitor.identifiers.dedup(); + let mut origin_visitor = BindingVisitor::default(); + for (_, pat) in &origin { + origin_visitor.visit_pat(pat); + } + origin_visitor.identifiers.sort(); + origin_visitor.identifiers.dedup(); + // Find if the binding could have been a typo + if let Some(typo) = + find_best_match_for_name(&target_visitor.identifiers, name.name, None) + && !origin_visitor.identifiers.contains(&typo) + { + err.subdiagnostic(errors::PatternBindingTypo { spans: origin_sp, typo }); + suggested_typo = true; + } } if could_be_path { let import_suggestions = self.lookup_import_candidates( diff --git a/tests/ui/or-patterns/binding-typo-2.rs b/tests/ui/or-patterns/binding-typo-2.rs index fe4a20536d7..275b68a22e2 100644 --- a/tests/ui/or-patterns/binding-typo-2.rs +++ b/tests/ui/or-patterns/binding-typo-2.rs @@ -47,7 +47,7 @@ fn foo(x: (Lol, Lol)) { //~| ERROR: variable `Non` is not bound in all patterns [E0408] //~| NOTE: pattern doesn't bind `Non` //~| NOTE: variable not in all patterns - //~| HELP: you might have meant to use the similarly named previously used binding `None` + //~| HELP: you might have meant to use the similarly named unit variant `None` //~| HELP: you might have meant to pattern match on the similarly named } match Some(42) { diff --git a/tests/ui/or-patterns/binding-typo-2.stderr b/tests/ui/or-patterns/binding-typo-2.stderr index fc6d02d65a4..81ea6e6b1bc 100644 --- a/tests/ui/or-patterns/binding-typo-2.stderr +++ b/tests/ui/or-patterns/binding-typo-2.stderr @@ -34,10 +34,11 @@ LL | Non | None => {} | | | variable not in all patterns | -help: you might have meant to use the similarly named previously used binding `None` +help: you might have meant to use the similarly named unit variant `None` + | +LL - Non | None => {} +LL + core::option::Option::None | None => {} | -LL | None | None => {} - | + error[E0408]: variable `Non` is not bound in all patterns --> $DIR/binding-typo-2.rs:54:15 diff --git a/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr b/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr index 523cdf959e7..81602fffa8d 100644 --- a/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr +++ b/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr @@ -5,12 +5,6 @@ LL | async fn a((x | s): String) {} | ^ - variable not in all patterns | | | pattern doesn't bind `s` - | -help: you might have meant to use the similarly named previously used binding `x` - | -LL - async fn a((x | s): String) {} -LL + async fn a((x | x): String) {} - | error[E0408]: variable `x` is not bound in all patterns --> $DIR/mismatched-bindings-async-fn.rs:4:17 @@ -19,12 +13,6 @@ LL | async fn a((x | s): String) {} | - ^ pattern doesn't bind `x` | | | variable not in all patterns - | -help: you might have meant to use the similarly named previously used binding `s` - | -LL - async fn a((x | s): String) {} -LL + async fn a((s | s): String) {} - | error[E0408]: variable `s` is not bound in all patterns --> $DIR/mismatched-bindings-async-fn.rs:9:10 @@ -33,12 +21,6 @@ LL | let (x | s) = String::new(); | ^ - variable not in all patterns | | | pattern doesn't bind `s` - | -help: you might have meant to use the similarly named previously used binding `x` - | -LL - let (x | s) = String::new(); -LL + let (x | x) = String::new(); - | error[E0408]: variable `x` is not bound in all patterns --> $DIR/mismatched-bindings-async-fn.rs:9:14 @@ -47,12 +29,6 @@ LL | let (x | s) = String::new(); | - ^ pattern doesn't bind `x` | | | variable not in all patterns - | -help: you might have meant to use the similarly named previously used binding `s` - | -LL - let (x | s) = String::new(); -LL + let (s | s) = String::new(); - | error: aborting due to 4 previous errors diff --git a/tests/ui/or-patterns/nested-undelimited-precedence.stderr b/tests/ui/or-patterns/nested-undelimited-precedence.stderr index 10dbc9d16c0..0835ca1929f 100644 --- a/tests/ui/or-patterns/nested-undelimited-precedence.stderr +++ b/tests/ui/or-patterns/nested-undelimited-precedence.stderr @@ -60,12 +60,6 @@ LL | let b @ A | B: E = A; | - ^ pattern doesn't bind `b` | | | variable not in all patterns - | -help: you might have meant to use the similarly named previously used binding `B` - | -LL - let b @ A | B: E = A; -LL + let B @ A | B: E = A; - | error[E0308]: mismatched types --> $DIR/nested-undelimited-precedence.rs:34:9 diff --git a/tests/ui/resolve/resolve-inconsistent-names.rs b/tests/ui/resolve/resolve-inconsistent-names.rs index bf74a4ba0f3..96504720e83 100644 --- a/tests/ui/resolve/resolve-inconsistent-names.rs +++ b/tests/ui/resolve/resolve-inconsistent-names.rs @@ -12,8 +12,6 @@ fn main() { match y { a | b => {} //~ ERROR variable `a` is not bound in all patterns //~| ERROR variable `b` is not bound in all patterns - //~| HELP you might have meant to use the similarly named previously used binding `a` - //~| HELP you might have meant to use the similarly named previously used binding `b` } let x = (E::A, E::B); diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr index 152c16ad404..d2333150961 100644 --- a/tests/ui/resolve/resolve-inconsistent-names.stderr +++ b/tests/ui/resolve/resolve-inconsistent-names.stderr @@ -5,12 +5,6 @@ LL | a | b => {} | ^ - variable not in all patterns | | | pattern doesn't bind `b` - | -help: you might have meant to use the similarly named previously used binding `a` - | -LL - a | b => {} -LL + a | a => {} - | error[E0408]: variable `a` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:13:13 @@ -19,15 +13,9 @@ LL | a | b => {} | - ^ pattern doesn't bind `a` | | | variable not in all patterns - | -help: you might have meant to use the similarly named previously used binding `b` - | -LL - a | b => {} -LL + b | b => {} - | error[E0408]: variable `c` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:21:9 + --> $DIR/resolve-inconsistent-names.rs:19:9 | LL | (A, B) | (ref B, c) | (c, A) => () | ^^^^^^ - - variable not in all patterns @@ -36,7 +24,7 @@ LL | (A, B) | (ref B, c) | (c, A) => () | pattern doesn't bind `c` error[E0408]: variable `A` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:21:18 + --> $DIR/resolve-inconsistent-names.rs:19:18 | LL | (A, B) | (ref B, c) | (c, A) => () | - ^^^^^^^^^^ - variable not in all patterns @@ -50,7 +38,7 @@ LL | (E::A, B) | (ref B, c) | (c, A) => () | +++ error[E0408]: variable `B` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:21:31 + --> $DIR/resolve-inconsistent-names.rs:19:31 | LL | (A, B) | (ref B, c) | (c, A) => () | - - ^^^^^^ pattern doesn't bind `B` @@ -59,7 +47,7 @@ LL | (A, B) | (ref B, c) | (c, A) => () | variable not in all patterns error[E0409]: variable `B` is bound inconsistently across alternatives separated by `|` - --> $DIR/resolve-inconsistent-names.rs:21:23 + --> $DIR/resolve-inconsistent-names.rs:19:23 | LL | (A, B) | (ref B, c) | (c, A) => () | - ^ bound in different ways @@ -67,7 +55,7 @@ LL | (A, B) | (ref B, c) | (c, A) => () | first binding error[E0408]: variable `Const2` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:33:9 + --> $DIR/resolve-inconsistent-names.rs:31:9 | LL | (CONST1, _) | (_, Const2) => () | ^^^^^^^^^^^ ------ variable not in all patterns @@ -80,7 +68,7 @@ LL | (CONST1, _) | (_, m::Const2) => () | +++ error[E0408]: variable `CONST1` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:33:23 + --> $DIR/resolve-inconsistent-names.rs:31:23 | LL | (CONST1, _) | (_, Const2) => () | ------ ^^^^^^^^^^^ pattern doesn't bind `CONST1` @@ -94,7 +82,7 @@ LL | const CONST1: usize = 10; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible error[E0308]: mismatched types - --> $DIR/resolve-inconsistent-names.rs:21:19 + --> $DIR/resolve-inconsistent-names.rs:19:19 | LL | match x { | - this expression has type `(E, E)` |
