diff options
author | Marcus Klaas de Vries <[email protected]> | 2019-01-28 22:06:11 +0000 |
---|---|---|
committer | Marcus Klaas de Vries <[email protected]> | 2019-01-28 22:09:14 +0000 |
commit | 3daca3eb4d843199540edfb1092f57f49938d0f6 (patch) | |
tree | 4cdc5c921b024d8b348b73e1a7c3e6a56fc11305 /crates/ra_hir/src | |
parent | 3f4f50baaa21cb2d0f6c102f1ca521946071a8dc (diff) |
Infer type of match guard
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 3 |
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)] |
216 | pub struct MatchArm { | 216 | pub 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 | --- |
2 | created: "2019-01-22T14:44:59.880187500+00:00" | 2 | created: "2019-01-28T21:58:55.559331849+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&result" | 4 | expression: "&result" |
5 | source: "crates\\ra_hir\\src\\ty\\tests.rs" | 5 | source: 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; |