From 06d16a18f632711de588ccd12a6a1ed6f2b9ad69 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Thu, 17 Jan 2019 00:29:26 +0100 Subject: Implement match binding type inference and arm unification --- crates/ra_hir/src/ty.rs | 24 +++++++++++++++++------- crates/ra_hir/src/ty/tests/data/adt_pattern.txt | 9 ++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 66940ec30..74996dda5 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -36,7 +36,7 @@ use crate::{ db::HirDatabase, type_ref::{TypeRef, Mutability}, name::KnownName, - expr::{Body, Expr, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, + expr::{Body, Expr, MatchArm, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, }; /// The ID of a type variable. @@ -1097,14 +1097,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ret_ty } Expr::Match { expr, arms } => { - let _ty = self.infer_expr(*expr, &Expectation::none()); - for arm in arms { - // TODO type the bindings in pats + let mut expected = Expectation::none(); + let input_ty = self.infer_expr(*expr, &Expectation::none()); + let pat_expectation = Expectation::has_type(input_ty); + + for MatchArm { + pats, + expr: arm_expr, + } in arms + { + for &pat in pats { + let _pat_ty = self.infer_pat(pat, &pat_expectation); + } // TODO type the guard - let _ty = self.infer_expr(arm.expr, &Expectation::none()); + let ty = self.infer_expr(*arm_expr, &expected); + expected = Expectation::has_type(ty); } - // TODO unify all the match arm types - Ty::Unknown + + expected.ty } Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown), Expr::Continue => Ty::Never, diff --git a/crates/ra_hir/src/ty/tests/data/adt_pattern.txt b/crates/ra_hir/src/ty/tests/data/adt_pattern.txt index 41e9c9d34..3b9b9a078 100644 --- a/crates/ra_hir/src/ty/tests/data/adt_pattern.txt +++ b/crates/ra_hir/src/ty/tests/data/adt_pattern.txt @@ -1,4 +1,4 @@ -[68; 155) '{ ...= e; }': () +[68; 221) '{ ... }; }': () [78; 79) 'e': E [82; 95) 'E::A { x: 3 }': E [92; 93) '3': usize @@ -9,3 +9,10 @@ [129; 148) 'E::A {..._var }': E [139; 146) 'new_var': usize [151; 152) 'e': E +[159; 218) 'match ... }': usize +[165; 166) 'e': E +[177; 187) 'E::A { x }': E +[184; 185) 'x': usize +[191; 192) 'x': usize +[202; 206) 'E::B': E +[210; 211) '1': usize -- cgit v1.2.3