From 44e2c6ea9207264a86d05344b67999d77687edb6 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Fri, 3 Mar 2023 10:41:09 +0100
Subject: [PATCH] Don't emit two type mismatches for literal pattern mismatches

---
 crates/hir-ty/src/infer/pat.rs                       | 11 ++++++++---
 crates/ide-diagnostics/src/handlers/type_mismatch.rs | 11 +----------
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 6481e0b7a71..4c97eabd9ce 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -181,8 +181,8 @@ impl<'a> InferenceContext<'a> {
             .intern(Interner)
     }
 
-    pub(super) fn infer_top_pat(&mut self, pat: PatId, expected: &Ty) -> Ty {
-        self.infer_pat(pat, expected, BindingMode::default())
+    pub(super) fn infer_top_pat(&mut self, pat: PatId, expected: &Ty) {
+        self.infer_pat(pat, expected, BindingMode::default());
     }
 
     fn infer_pat(&mut self, pat: PatId, expected: &Ty, mut default_bm: BindingMode) -> Ty {
@@ -260,7 +260,12 @@ impl<'a> InferenceContext<'a> {
                 let start_ty = self.infer_expr(*start, &Expectation::has_type(expected.clone()));
                 self.infer_expr(*end, &Expectation::has_type(start_ty))
             }
-            &Pat::Lit(expr) => self.infer_lit_pat(expr, &expected),
+            &Pat::Lit(expr) => {
+                // Don't emit type mismatches again, the expression lowering already did that.
+                let ty = self.infer_lit_pat(expr, &expected);
+                self.write_pat_ty(pat, ty.clone());
+                return ty;
+            }
             Pat::Box { inner } => match self.resolve_boxed_box() {
                 Some(box_adt) => {
                     let (inner_ty, alloc_ty) = match expected.as_adt() {
diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
index 948ca4f6328..2026a2d4b8a 100644
--- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs
+++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -54,7 +54,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Option<Vec<Assi
             remove_semicolon(ctx, d, expr_ptr, &mut fixes);
             str_ref_to_owned(ctx, d, expr_ptr, &mut fixes);
         }
-        Either::Right(_pat_ptr) => (),
+        Either::Right(_pat_ptr) => {}
     }
 
     if fixes.is_empty() {
@@ -63,14 +63,6 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Option<Vec<Assi
         Some(fixes)
     }
 }
-fn add_reference_pat(
-    ctx: &DiagnosticsContext<'_>,
-    d: &hir::TypeMismatch,
-    expr_ptr: &InFile<AstPtr<ast::Pat>>,
-    acc: &mut Vec<Assist>,
-) -> Option<()> {
-    None
-}
 
 fn add_reference(
     ctx: &DiagnosticsContext<'_>,
@@ -630,7 +622,6 @@ fn f() {
         &9 => ()
       //^^ error: expected &(), found &i32
        //^ error: expected (), found i32
-       //^ error: expected (), found i32
     }
 }
 "#,