about summary refs log tree commit diff
path: root/compiler/rustc_resolve
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 /compiler/rustc_resolve
parent3355f4bced511aba46c5a92ea82241b6713331ba (diff)
downloadrust-86085b4f65fae0ebc456202584e7e04b58a871f3.tar.gz
rust-86085b4f65fae0ebc456202584e7e04b58a871f3.zip
Avoid unnecessary suggestion in or-pattern
Diffstat (limited to 'compiler/rustc_resolve')
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs42
1 files changed, 24 insertions, 18 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(