mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-03 21:47:36 +00:00
Make let statements kind of work
This commit is contained in:
parent
5d60937090
commit
93ffbf80c6
@ -243,8 +243,23 @@ impl InferenceContext {
|
|||||||
self.type_for.insert(LocalSyntaxPtr::new(node), ty);
|
self.type_for.insert(LocalSyntaxPtr::new(node), ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unify(&mut self, _ty1: &Ty, _ty2: &Ty) -> bool {
|
fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> Option<Ty> {
|
||||||
unimplemented!()
|
if *ty1 == Ty::Unknown {
|
||||||
|
return Some(ty2.clone());
|
||||||
|
}
|
||||||
|
if *ty2 == Ty::Unknown {
|
||||||
|
return Some(ty1.clone());
|
||||||
|
}
|
||||||
|
if ty1 == ty2 {
|
||||||
|
return Some(ty1.clone());
|
||||||
|
}
|
||||||
|
// TODO implement actual unification
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unify_with_coercion(&mut self, ty1: &Ty, ty2: &Ty) -> Option<Ty> {
|
||||||
|
// TODO implement coercion
|
||||||
|
self.unify(ty1, ty2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Option<Ty> {
|
fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Option<Ty> {
|
||||||
@ -280,9 +295,8 @@ impl InferenceContext {
|
|||||||
} else {
|
} else {
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
};
|
};
|
||||||
if self.unify(&if_ty, &else_ty) {
|
if let Some(ty) = self.unify(&if_ty, &else_ty) {
|
||||||
// TODO actually, need to take the 'more specific' type (not unknown, never, ...)
|
ty
|
||||||
if_ty
|
|
||||||
} else {
|
} else {
|
||||||
// TODO report diagnostic
|
// TODO report diagnostic
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
@ -455,9 +469,23 @@ impl InferenceContext {
|
|||||||
for stmt in node.statements() {
|
for stmt in node.statements() {
|
||||||
match stmt {
|
match stmt {
|
||||||
ast::Stmt::LetStmt(stmt) => {
|
ast::Stmt::LetStmt(stmt) => {
|
||||||
if let Some(expr) = stmt.initializer() {
|
let decl_ty = if let Some(type_ref) = stmt.type_ref() {
|
||||||
self.infer_expr(expr);
|
Ty::new(type_ref)
|
||||||
}
|
} else {
|
||||||
|
Ty::Unknown
|
||||||
|
};
|
||||||
|
let ty = if let Some(expr) = stmt.initializer() {
|
||||||
|
// TODO pass expectation
|
||||||
|
let expr_ty = self.infer_expr(expr);
|
||||||
|
self.unify_with_coercion(&expr_ty, &decl_ty)
|
||||||
|
.unwrap_or(decl_ty)
|
||||||
|
} else {
|
||||||
|
decl_ty
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(pat) = stmt.pat() {
|
||||||
|
self.write_ty(pat.syntax(), ty);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
ast::Stmt::ExprStmt(expr_stmt) => {
|
ast::Stmt::ExprStmt(expr_stmt) => {
|
||||||
if let Some(expr) = expr_stmt.expr() {
|
if let Some(expr) = expr_stmt.expr() {
|
||||||
|
5
crates/ra_hir/src/ty/tests/data/0002_let.rs
Normal file
5
crates/ra_hir/src/ty/tests/data/0002_let.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
fn test() {
|
||||||
|
let a = 1isize;
|
||||||
|
let b: usize = 1;
|
||||||
|
let c = b;
|
||||||
|
}
|
7
crates/ra_hir/src/ty/tests/data/0002_let.txt
Normal file
7
crates/ra_hir/src/ty/tests/data/0002_let.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[51; 52) '1': [unknown]
|
||||||
|
[10; 70) '{ ...= b; }': ()
|
||||||
|
[24; 30) '1isize': [unknown]
|
||||||
|
[20; 21) 'a': [unknown]
|
||||||
|
[62; 63) 'c': usize
|
||||||
|
[66; 67) 'b': usize
|
||||||
|
[40; 41) 'b': usize
|
@ -1561,6 +1561,10 @@ impl<'a> LetStmt<'a> {
|
|||||||
super::child_opt(self)
|
super::child_opt(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_ref(self) -> Option<TypeRef<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn initializer(self) -> Option<Expr<'a>> {
|
pub fn initializer(self) -> Option<Expr<'a>> {
|
||||||
super::child_opt(self)
|
super::child_opt(self)
|
||||||
}
|
}
|
||||||
|
@ -499,6 +499,7 @@ Grammar(
|
|||||||
),
|
),
|
||||||
"LetStmt": ( options: [
|
"LetStmt": ( options: [
|
||||||
["pat", "Pat"],
|
["pat", "Pat"],
|
||||||
|
["type_ref", "TypeRef"],
|
||||||
["initializer", "Expr"],
|
["initializer", "Expr"],
|
||||||
]),
|
]),
|
||||||
"Condition": (
|
"Condition": (
|
||||||
|
Loading…
Reference in New Issue
Block a user