diff options
Diffstat (limited to 'crates')
-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 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 1 |
5 files changed, 53 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 | ||
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 74bf4d3cc..b15c4ef6f 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1561,6 +1561,10 @@ impl<'a> LetStmt<'a> { | |||
1561 | super::child_opt(self) | 1561 | super::child_opt(self) |
1562 | } | 1562 | } |
1563 | 1563 | ||
1564 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
1565 | super::child_opt(self) | ||
1566 | } | ||
1567 | |||
1564 | pub fn initializer(self) -> Option<Expr<'a>> { | 1568 | pub fn initializer(self) -> Option<Expr<'a>> { |
1565 | super::child_opt(self) | 1569 | super::child_opt(self) |
1566 | } | 1570 | } |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 29b84854a..8dca493ee 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -499,6 +499,7 @@ Grammar( | |||
499 | ), | 499 | ), |
500 | "LetStmt": ( options: [ | 500 | "LetStmt": ( options: [ |
501 | ["pat", "Pat"], | 501 | ["pat", "Pat"], |
502 | ["type_ref", "TypeRef"], | ||
502 | ["initializer", "Expr"], | 503 | ["initializer", "Expr"], |
503 | ]), | 504 | ]), |
504 | "Condition": ( | 505 | "Condition": ( |