diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 44 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0002_let.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0002_let.txt | 7 |
3 files changed, 48 insertions, 8 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index eb5fea153..615a1caed 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -243,8 +243,23 @@ impl InferenceContext { | |||
243 | self.type_for.insert(LocalSyntaxPtr::new(node), ty); | 243 | self.type_for.insert(LocalSyntaxPtr::new(node), ty); |
244 | } | 244 | } |
245 | 245 | ||
246 | fn unify(&mut self, _ty1: &Ty, _ty2: &Ty) -> bool { | 246 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> Option<Ty> { |
247 | unimplemented!() | 247 | if *ty1 == Ty::Unknown { |
248 | return Some(ty2.clone()); | ||
249 | } | ||
250 | if *ty2 == Ty::Unknown { | ||
251 | return Some(ty1.clone()); | ||
252 | } | ||
253 | if ty1 == ty2 { | ||
254 | return Some(ty1.clone()); | ||
255 | } | ||
256 | // TODO implement actual unification | ||
257 | return None; | ||
258 | } | ||
259 | |||
260 | fn unify_with_coercion(&mut self, ty1: &Ty, ty2: &Ty) -> Option<Ty> { | ||
261 | // TODO implement coercion | ||
262 | self.unify(ty1, ty2) | ||
248 | } | 263 | } |
249 | 264 | ||
250 | fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Option<Ty> { | 265 | fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Option<Ty> { |
@@ -280,9 +295,8 @@ impl InferenceContext { | |||
280 | } else { | 295 | } else { |
281 | Ty::Unknown | 296 | Ty::Unknown |
282 | }; | 297 | }; |
283 | if self.unify(&if_ty, &else_ty) { | 298 | if let Some(ty) = self.unify(&if_ty, &else_ty) { |
284 | // TODO actually, need to take the 'more specific' type (not unknown, never, ...) | 299 | ty |
285 | if_ty | ||
286 | } else { | 300 | } else { |
287 | // TODO report diagnostic | 301 | // TODO report diagnostic |
288 | Ty::Unknown | 302 | Ty::Unknown |
@@ -455,9 +469,23 @@ impl InferenceContext { | |||
455 | for stmt in node.statements() { | 469 | for stmt in node.statements() { |
456 | match stmt { | 470 | match stmt { |
457 | ast::Stmt::LetStmt(stmt) => { | 471 | ast::Stmt::LetStmt(stmt) => { |
458 | if let Some(expr) = stmt.initializer() { | 472 | let decl_ty = if let Some(type_ref) = stmt.type_ref() { |
459 | self.infer_expr(expr); | 473 | Ty::new(type_ref) |
460 | } | 474 | } else { |
475 | Ty::Unknown | ||
476 | }; | ||
477 | let ty = if let Some(expr) = stmt.initializer() { | ||
478 | // TODO pass expectation | ||
479 | let expr_ty = self.infer_expr(expr); | ||
480 | self.unify_with_coercion(&expr_ty, &decl_ty) | ||
481 | .unwrap_or(decl_ty) | ||
482 | } else { | ||
483 | decl_ty | ||
484 | }; | ||
485 | |||
486 | if let Some(pat) = stmt.pat() { | ||
487 | self.write_ty(pat.syntax(), ty); | ||
488 | }; | ||
461 | } | 489 | } |
462 | ast::Stmt::ExprStmt(expr_stmt) => { | 490 | ast::Stmt::ExprStmt(expr_stmt) => { |
463 | if let Some(expr) = expr_stmt.expr() { | 491 | if let Some(expr) = expr_stmt.expr() { |
diff --git a/crates/ra_hir/src/ty/tests/data/0002_let.rs b/crates/ra_hir/src/ty/tests/data/0002_let.rs new file mode 100644 index 000000000..5641da75b --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/0002_let.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn test() { | ||
2 | let a = 1isize; | ||
3 | let b: usize = 1; | ||
4 | let c = b; | ||
5 | } | ||
diff --git a/crates/ra_hir/src/ty/tests/data/0002_let.txt b/crates/ra_hir/src/ty/tests/data/0002_let.txt new file mode 100644 index 000000000..5f515ee59 --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/0002_let.txt | |||
@@ -0,0 +1,7 @@ | |||
1 | [51; 52) '1': [unknown] | ||
2 | [10; 70) '{ ...= b; }': () | ||
3 | [24; 30) '1isize': [unknown] | ||
4 | [20; 21) 'a': [unknown] | ||
5 | [62; 63) 'c': usize | ||
6 | [66; 67) 'b': usize | ||
7 | [40; 41) 'b': usize | ||