diff options
-rw-r--r-- | src/hir_typeck/expr.cpp | 25 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 33 |
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() ) |