about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-08-30 17:44:23 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-08-30 17:44:23 +0000
commit86085b4f65fae0ebc456202584e7e04b58a871f3 (patch)
tree85df0b601b3ade0ffeed6064744294ce83c36bb1
parent3355f4bced511aba46c5a92ea82241b6713331ba (diff)
downloadrust-86085b4f65fae0ebc456202584e7e04b58a871f3.tar.gz
rust-86085b4f65fae0ebc456202584e7e04b58a871f3.zip
Avoid unnecessary suggestion in or-pattern
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs42
-rw-r--r--tests/ui/or-patterns/binding-typo-2.rs2
-rw-r--r--tests/ui/or-patterns/binding-typo-2.stderr7
-rw-r--r--tests/ui/or-patterns/mismatched-bindings-async-fn.stderr24
-rw-r--r--tests/ui/or-patterns/nested-undelimited-precedence.stderr6
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.rs2
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.stderr26
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)`