diff --git a/crates/hir_ty/src/diagnostics/pattern.rs b/crates/hir_ty/src/diagnostics/pattern.rs
index 14dd736a6cb..99f32097f74 100644
--- a/crates/hir_ty/src/diagnostics/pattern.rs
+++ b/crates/hir_ty/src/diagnostics/pattern.rs
@@ -11,7 +11,7 @@ use la_arena::Idx;
 
 use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, Substitution, Ty, TyKind};
 
-use self::{deconstruct_pat::ToDo, pat_util::EnumerateAndAdjustIterator};
+use self::pat_util::EnumerateAndAdjustIterator;
 
 pub type PatId = Idx<Pat>;
 
@@ -45,7 +45,6 @@ pub enum PatKind {
     /// `x`, `ref x`, `x @ P`, etc.
     Binding {
         subpattern: Option<Pat>,
-        // todo: ToDo,
     },
 
     /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
@@ -119,6 +118,10 @@ impl<'a> PatCtxt<'a> {
                 PatKind::Leaf { subpatterns }
             }
 
+            hir_def::expr::Pat::Bind { subpat, .. } => {
+                PatKind::Binding { subpattern: self.lower_opt_pattern(subpat) }
+            }
+
             hir_def::expr::Pat::TupleStruct { ref args, ellipsis, .. } => {
                 let variant_data = match self.infer.variant_resolution_for_pat(pat) {
                     Some(variant_id) => variant_id.variant_data(self.db.upcast()),
@@ -175,6 +178,10 @@ impl<'a> PatCtxt<'a> {
         pats.iter().map(|&p| self.lower_pattern(p)).collect()
     }
 
+    fn lower_opt_pattern(&mut self, pat: Option<hir_def::expr::PatId>) -> Option<Pat> {
+        pat.map(|p| self.lower_pattern(p))
+    }
+
     fn lower_variant_or_leaf(
         &mut self,
         pat: hir_def::expr::PatId,
@@ -383,13 +390,30 @@ fn main() {
 struct S { a: char}
 fn main(v: S) {
     match v { S{ a }      => {} }
-    match v { S{ a: x }   => {} }
+    match v { S{ a: _x }   => {} }
     match v { S{ a: 'a' } => {} }
     match v { S{..}       => {} }
     match v { _           => {} }
     match v { }
         //^ Missing match arm
 }
+"#,
+        );
+    }
+
+    #[test]
+    fn binding() {
+        check_diagnostics(
+            r#"
+fn main() {
+    match true {
+        _x @ true => {}
+        false     => {}
+    }
+    //FIXME: false negative. 
+    // Binding patterns should be expanded in `usefulness::expand_pattern()`
+    match true { _x @ true => {} }
+}
 "#,
         );
     }
diff --git a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs
index 91b9c7184d8..1c86ed59bdc 100644
--- a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs
+++ b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs
@@ -801,12 +801,7 @@ impl Fields {
         cx: &MatchCheckCtx<'_>,
         pats: impl IntoIterator<Item = Pat>,
     ) -> Self {
-        let pats = {
-            let tys: SmallVec<[Ty; 2]> = match self {
-                Fields::Vec(pats) => pats.iter().copied().map(|pat| cx.type_of(pat)).collect(),
-            };
-            pats.into_iter().zip(tys.into_iter()).map(move |(pat, ty)| cx.alloc_pat(pat)).collect()
-        };
+        let pats = pats.into_iter().map(|pat| cx.alloc_pat(pat)).collect();
 
         match self {
             Fields::Vec(_) => Fields::Vec(pats),