Implement tuple inference

This commit is contained in:
Hirokazu Hata 2019-01-13 21:00:27 +09:00
parent 6efda8f6ce
commit 6e73cc89b6
2 changed files with 20 additions and 1 deletions

View file

@ -183,6 +183,9 @@ pub enum Expr {
arg_types: Vec<Option<TypeRef>>, arg_types: Vec<Option<TypeRef>>,
body: ExprId, body: ExprId,
}, },
Tuple {
exprs: Vec<ExprId>,
},
} }
pub use ra_syntax::ast::PrefixOp as UnaryOp; pub use ra_syntax::ast::PrefixOp as UnaryOp;
@ -297,6 +300,11 @@ impl Expr {
| Expr::UnaryOp { expr, .. } => { | Expr::UnaryOp { expr, .. } => {
f(*expr); f(*expr);
} }
Expr::Tuple { exprs } => {
for expr in exprs {
f(*expr);
}
}
} }
} }
} }
@ -621,11 +629,14 @@ impl ExprCollector {
let op = e.op(); let op = e.op();
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
} }
ast::ExprKind::TupleExpr(e) => {
let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
}
// TODO implement HIR for these: // TODO implement HIR for these:
ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
ast::ExprKind::TupleExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),

View file

@ -1040,6 +1040,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
} }
_ => Ty::Unknown, _ => Ty::Unknown,
}, },
Expr::Tuple { exprs } => {
let mut ty_vec = Vec::with_capacity(exprs.len());
for arg in exprs.iter() {
ty_vec.push(self.infer_expr(*arg, &Expectation::none())?);
}
Ty::Tuple(Arc::from(ty_vec))
}
}; };
// use a new type variable if we got Ty::Unknown here // use a new type variable if we got Ty::Unknown here
let ty = self.insert_type_vars_shallow(ty); let ty = self.insert_type_vars_shallow(ty);