summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_typeck/expr.cpp50
-rw-r--r--src/hir_typeck/expr_context.cpp8
2 files changed, 48 insertions, 10 deletions
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index 6ab12439..1dc09dce 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -349,21 +349,39 @@ namespace typeck {
}
void visit(::HIR::ExprNode_Block& node) override
{
- this->context.push_traits( node.m_traits );
- ::HIR::ExprVisitorDef::visit(node);
if( node.m_nodes.size() > 0 ) {
- auto& ln = *node.m_nodes.back();
- this->context.apply_equality(ln.span(), node.m_res_type, ln.m_res_type, &node.m_nodes.back());
+ auto unit = ::HIR::TypeRef::new_unit();
+ for(unsigned int i = 0; i < node.m_nodes.size()-1; i++) {
+ auto& n = node.m_nodes[i];
+ if( dynamic_cast< ::HIR::ExprNode_Block*>(&*n) ) {
+ this->context.add_ivars(n->m_res_type);
+ this->context.apply_equality(n->span(), unit, n->m_res_type, &n);
+ }
+ }
+ auto& ln = node.m_nodes.back();
+ this->context.add_ivars(ln->m_res_type);
+ this->context.apply_equality(ln->span(), node.m_res_type, ln->m_res_type, &ln);
}
else {
node.m_res_type = ::HIR::TypeRef::new_unit();
}
+
+ this->context.push_traits( node.m_traits );
+ ::HIR::ExprVisitorDef::visit(node);
this->context.pop_traits( node.m_traits );
}
void visit(::HIR::ExprNode_Return& node) override
{
- ::HIR::ExprVisitorDef::visit(node);
+ this->context.add_ivars( node.m_value->m_res_type );
this->context.apply_equality(node.span(), this->ret_type, node.m_value->m_res_type, &node.m_value);
+ ::HIR::ExprVisitorDef::visit(node);
+ }
+
+ void visit(::HIR::ExprNode_Loop& node) override
+ {
+ this->context.add_ivars( node.m_code->m_res_type );
+ this->context.apply_equality(node.span(), ::HIR::TypeRef::new_unit(), node.m_code->m_res_type, &node.m_code);
+ ::HIR::ExprVisitorDef::visit(node);
}
void visit(::HIR::ExprNode_Let& node) override
@@ -389,18 +407,22 @@ namespace typeck {
{
this->context.add_binding(node.span(), pat, node.m_value->m_res_type);
}
+
+ this->context.add_ivars( arm.m_code->m_res_type );
+ this->context.apply_equality(node.span(), node.m_res_type, arm.m_code->m_res_type, &arm.m_code);
}
DEBUG("- match val : " << this->context.get_type(node.m_value->m_res_type));
-
::HIR::ExprVisitorDef::visit(node);
DEBUG("- match val : " << this->context.get_type(node.m_value->m_res_type));
}
void visit(::HIR::ExprNode_If& node) override
{
node.m_cond->m_res_type = ::HIR::TypeRef( ::HIR::CoreType::Bool );
+ this->context.add_ivars( node.m_true->m_res_type );
if( node.m_false ) {
- // node.m_true->m_res_type = node.m_res_type.clone();
- // node.m_false->m_res_type = node.m_res_type.clone();
+ this->context.add_ivars( node.m_false->m_res_type );
+ this->context.apply_equality(node.span(), node.m_res_type, node.m_true->m_res_type, &node.m_true);
+ this->context.apply_equality(node.span(), node.m_res_type, node.m_false->m_res_type, &node.m_false);
}
else {
this->context.apply_equality(node.span(), node.m_res_type, ::HIR::TypeRef::new_unit());
@@ -1947,6 +1969,9 @@ namespace typeck {
{
auto& ty = this->context.get_type(node.m_res_type);
if( !ty.m_data.is_Tuple() ) {
+ if( ty.m_data.is_Diverge() ) {
+ return ;
+ }
this->context.dump();
BUG(node.span(), "Return type of tuple literal wasn't a tuple - " << node.m_res_type << " = " << ty);
}
@@ -2082,8 +2107,13 @@ void Typecheck_Code(typeck::TypecheckContext context, const ::HIR::TypeRef& resu
// 1. Enumerate inferrence variables and assign indexes to them
{
typeck::ExprVisitor_Enum visitor { context, result_type };
- context.add_ivars( root_ptr->m_res_type );
- context.apply_equality(root_ptr->span(), result_type, root_ptr->m_res_type, &root_ptr);
+ if( root_ptr->m_res_type.m_data.is_Infer() ) {
+ root_ptr->m_res_type = result_type.clone();
+ }
+ else {
+ context.add_ivars( root_ptr->m_res_type );
+ context.apply_equality(root_ptr->span(), result_type, root_ptr->m_res_type, &root_ptr);
+ }
visitor.visit_node_ptr(root_ptr);
}
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 01d933b2..0bef9445 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -1042,6 +1042,14 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
return ;
}
+ if( /*l_t.m_data.is_Diverge() ||*/ r_t.m_data.is_Diverge() ) {
+ DEBUG("Refusing to unify with !");
+ return ;
+ }
+ if( l_t.m_data.is_Diverge() ) {
+ // TODO: Error if the right type isn't infer
+ }
+
DEBUG("- l_t = " << l_t << ", r_t = " << r_t);
TU_IFLET(::HIR::TypeRef::Data, r_t.m_data, Infer, r_e,
TU_IFLET(::HIR::TypeRef::Data, l_t.m_data, Infer, l_e,