aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-28 22:06:11 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-28 22:09:14 +0000
commit3daca3eb4d843199540edfb1092f57f49938d0f6 (patch)
tree4cdc5c921b024d8b348b73e1a7c3e6a56fc11305 /crates/ra_hir/src
parent3f4f50baaa21cb2d0f6c102f1ca521946071a8dc (diff)
Infer type of match guard
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs8
-rw-r--r--crates/ra_hir/src/ty.rs16
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap23
-rw-r--r--crates/ra_hir/src/ty/tests.rs3
4 files changed, 35 insertions, 15 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 60d997bbe..b01d53e5c 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -215,7 +215,7 @@ pub use ra_syntax::ast::BinOp as BinaryOp;
215#[derive(Debug, Clone, Eq, PartialEq)] 215#[derive(Debug, Clone, Eq, PartialEq)]
216pub struct MatchArm { 216pub struct MatchArm {
217 pub pats: Vec<PatId>, 217 pub pats: Vec<PatId>,
218 // guard: Option<ExprId>, // TODO 218 pub guard: Option<ExprId>,
219 pub expr: ExprId, 219 pub expr: ExprId,
220} 220}
221 221
@@ -511,10 +511,12 @@ impl ExprCollector {
511 MatchArm { 511 MatchArm {
512 pats: vec![pat], 512 pats: vec![pat],
513 expr: then_branch, 513 expr: then_branch,
514 guard: None,
514 }, 515 },
515 MatchArm { 516 MatchArm {
516 pats: vec![placeholder_pat], 517 pats: vec![placeholder_pat],
517 expr: else_branch, 518 expr: else_branch,
519 guard: None,
518 }, 520 },
519 ]; 521 ];
520 self.alloc_expr( 522 self.alloc_expr(
@@ -613,6 +615,10 @@ impl ExprCollector {
613 .map(|arm| MatchArm { 615 .map(|arm| MatchArm {
614 pats: arm.pats().map(|p| self.collect_pat(p)).collect(), 616 pats: arm.pats().map(|p| self.collect_pat(p)).collect(),
615 expr: self.collect_expr_opt(arm.expr()), 617 expr: self.collect_expr_opt(arm.expr()),
618 guard: arm.guard().map(|guard| {
619 let e = guard.expr().expect("every guard should have an expr");
620 self.collect_expr(e)
621 }),
616 }) 622 })
617 .collect() 623 .collect()
618 } else { 624 } else {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 31ea45706..e2c7884b5 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -1395,7 +1395,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1395 for &pat in &arm.pats { 1395 for &pat in &arm.pats {
1396 let _pat_ty = self.infer_pat(pat, &input_ty); 1396 let _pat_ty = self.infer_pat(pat, &input_ty);
1397 } 1397 }
1398 // TODO type the guard 1398 if let Some(guard_expr) = arm.guard {
1399 self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool));
1400 }
1399 self.infer_expr(arm.expr, &expected); 1401 self.infer_expr(arm.expr, &expected);
1400 } 1402 }
1401 1403
@@ -1468,9 +1470,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1468 cast_ty 1470 cast_ty
1469 } 1471 }
1470 Expr::Ref { expr, mutability } => { 1472 Expr::Ref { expr, mutability } => {
1471 // TODO pass the expectation down 1473 let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty {
1472 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 1474 if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared {
1475 // TODO: throw type error - expected mut reference but found shared ref,
1476 // which cannot be coerced
1477 }
1478 Expectation::has_type((**subty).clone())
1479 } else {
1480 Expectation::none()
1481 };
1473 // TODO reference coercions etc. 1482 // TODO reference coercions etc.
1483 let inner_ty = self.infer_expr(*expr, &expectation);
1474 Ty::Ref(Arc::new(inner_ty), *mutability) 1484 Ty::Ref(Arc::new(inner_ty), *mutability)
1475 } 1485 }
1476 Expr::UnaryOp { expr, op } => { 1486 Expr::UnaryOp { expr, op } => {
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
index 2719f592e..48c83cbb2 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
@@ -1,10 +1,10 @@
1--- 1---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-28T21:58:55.559331849+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[68; 262) '{ ... d; }': () 7[68; 289) '{ ... d; }': ()
8[78; 79) 'e': E 8[78; 79) 'e': E
9[82; 95) 'E::A { x: 3 }': E 9[82; 95) 'E::A { x: 3 }': E
10[92; 93) '3': usize 10[92; 93) '3': usize
@@ -15,15 +15,18 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
15[129; 148) 'E::A {..._var }': E 15[129; 148) 'E::A {..._var }': E
16[139; 146) 'new_var': usize 16[139; 146) 'new_var': usize
17[151; 152) 'e': E 17[151; 152) 'e': E
18[159; 218) 'match ... }': usize 18[159; 245) 'match ... }': usize
19[165; 166) 'e': E 19[165; 166) 'e': E
20[177; 187) 'E::A { x }': E 20[177; 187) 'E::A { x }': E
21[184; 185) 'x': usize 21[184; 185) 'x': usize
22[191; 192) 'x': usize 22[191; 192) 'x': usize
23[202; 206) 'E::B': E 23[202; 206) 'E::B': E
24[210; 211) '1': usize 24[210; 213) 'foo': bool
25[229; 248) 'ref d ...{ .. }': &E 25[217; 218) '1': usize
26[237; 248) 'E::A { .. }': E 26[228; 232) 'E::B': E
27[251; 252) 'e': E 27[236; 238) '10': usize
28[258; 259) 'd': &E 28[256; 275) 'ref d ...{ .. }': &E
29[264; 275) 'E::A { .. }': E
30[278; 279) 'e': E
31[285; 286) 'd': &E
29 32
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index f74d6f5ea..8aa188059 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -421,7 +421,8 @@ fn test() {
421 421
422 match e { 422 match e {
423 E::A { x } => x, 423 E::A { x } => x,
424 E::B => 1, 424 E::B if foo => 1,
425 E::B => 10,
425 }; 426 };
426 427
427 let ref d @ E::A { .. } = e; 428 let ref d @ E::A { .. } = e;