summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr.cpp25
-rw-r--r--src/hir_typeck/expr_context.cpp33
2 files changed, 54 insertions, 4 deletions
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index ee29d1c0..2cc11bad 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -345,6 +345,15 @@ namespace typeck {
}
}
+ void visit(::HIR::ExprNode_ArraySized& node) override {
+ if(node.m_size_val == ~0u) {
+ BUG(node.span(), "sized array literal didn't have its size evaluated");
+ }
+
+ ::HIR::ExprVisitorDef::visit(node);
+
+ this->context.apply_equality( node.span(), node.m_res_type, ::HIR::TypeRef(::HIR::TypeRef::Data::make_Array({ box$(node.m_val->m_res_type.clone()), ::HIR::ExprPtr(), node.m_size_val })) );
+ }
void visit(::HIR::ExprNode_Tuple& node) override
{
::HIR::ExprVisitorDef::visit(node);
@@ -1025,7 +1034,7 @@ namespace typeck {
this->context.apply_equality(sp, arg_ty, arg_expr_ptr->m_res_type, &arg_expr_ptr);
}
- DEBUG("Rreturn: " << arg_types.back());
+ DEBUG("_TupleVariant - Return: " << arg_types.back());
this->context.apply_equality(sp, node.m_res_type, arg_types.back() /*, &this_node_ptr*/);
::HIR::ExprVisitorDef::visit(node);
@@ -1515,7 +1524,12 @@ namespace typeck {
// - Array list
void visit(::HIR::ExprNode_ArrayList& node) override
{
- const auto& val_type = *node.m_res_type.m_data.as_Array().inner;
+ auto& ty = this->context.get_type(node.m_res_type);
+ if( !ty.m_data.is_Array() ) {
+ this->context.dump();
+ BUG(node.span(), "Return type of array literal wasn't an array - " << node.m_res_type << " = " << ty);
+ }
+ const auto& val_type = *ty.m_data.as_Array().inner;
::HIR::ExprVisitorDef::visit(node);
for(auto& sn : node.m_vals)
this->context.apply_equality(sn->span(), val_type, sn->m_res_type, &sn);
@@ -1523,7 +1537,12 @@ namespace typeck {
// - Array (sized)
void visit(::HIR::ExprNode_ArraySized& node) override
{
- const auto& val_type = *node.m_res_type.m_data.as_Array().inner;
+ auto& ty = this->context.get_type(node.m_res_type);
+ if( !ty.m_data.is_Array() ) {
+ this->context.dump();
+ BUG(node.span(), "Return type of array literal wasn't an array - " << node.m_res_type << " = " << ty);
+ }
+ const auto& val_type = *ty.m_data.as_Array().inner;
::HIR::ExprVisitorDef::visit(node);
this->context.apply_equality(node.span(), val_type, node.m_val->m_res_type, &node.m_val);
}
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 93a0748d..5e982342 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -856,6 +856,13 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
}
// - If left is a trait object, right can unsize
if( left_inner_res.m_data.is_TraitObject() ) {
+ // If the righthand side is still an ivar
+ if( right_inner_res.m_data.is_Infer() ) {
+ // Assume it's valid for now, and return
+ return ;
+ }
+
+ const auto& e = left_inner_res.m_data.as_TraitObject();
if( right_inner_res.m_data.is_TraitObject() ) {
// TODO: Can Debug+Send be coerced to Debug?
if( left_inner_res != right_inner_res )
@@ -864,7 +871,31 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
return ;
}
- TODO(sp, "Unsize into trait object - " << l_t << " <- " << r_t);
+ // 1. Search for an implementation of the data trait for this type
+ bool succ = this->find_trait_impls(e.m_trait.m_path, right_inner_res, [&](const auto& args) {
+ if( args.m_types.size() > 0 )
+ TODO(sp, "Handle unsizing to traits with params");
+ return true;
+ });
+ if(!succ)
+ ERROR(sp, E0000, "Trait " << e.m_trait << " isn't implemented for " << right_inner_res );
+ for(const auto& marker : e.m_markers)
+ {
+ TODO(sp, "Check for marker trait impls ("<<marker<<") when unsizing to " << left_inner_res << " from " << right_inner_res);
+ //bool succ = this->find_trait_impls(e.m_trait.m_path, right_inner_res, [&](const auto& args) {
+ // if( args.m_types.size() > 0 )
+ // TODO(sp, "Handle unsizing to traits with params");
+ // return true;
+ // });
+ }
+
+ // Valid unsize, insert unsize operation
+ auto span = node_ptr->span();
+ node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Unsize( mv$(span), mv$(node_ptr), l_t.clone() ));
+ node_ptr->m_res_type = l_t.clone();
+
+ this->mark_change();
+ return ;
}
// - If left is a slice, right can unsize/deref
if( left_inner_res.m_data.is_Slice() && !right_inner_res.m_data.is_Slice() )