diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 9 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 33 | ||||
-rw-r--r-- | src/main.cpp | 10 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 21 |
5 files changed, 65 insertions, 10 deletions
@@ -17,7 +17,7 @@ SHELL = bash ifeq ($(DBGTPL),) else ifeq ($(DBGTPL),gdb) - DBG := echo -e "r\nbt 9\nq" | gdb --args + DBG := echo -e "r\nbt 10\nq" | gdb --args else ifeq ($(DBGTPL),valgrind) DBG := valgrind --leak-check=full --num-callers=35 else diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index 0c474e02..e18c9ddd 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -1011,6 +1011,7 @@ namespace typeck { // - If an impl block was found if( impl_ptr ) { + assert(impl_ptr->m_types.count("Output") != 0); const auto& type = impl_ptr->m_types.at("Output"); if( monomorphise_type_needed(type) ) { TODO(node.span(), "BinOp output = " << type); @@ -1116,6 +1117,7 @@ namespace typeck { { const auto& val_ty = this->context.get_type( node.m_value->m_res_type ); const auto& target_ty = this->context.get_type( node.m_res_type ); + TRACE_FUNCTION_F("Cast {" << val_ty << "} as " << target_ty); TU_MATCH_DEF(::HIR::TypeRef::Data, (target_ty.m_data), (e), ( ERROR(node.span(), E0000, "Invalid cast"); @@ -1154,11 +1156,13 @@ namespace typeck { if( e.type != e2.type ) { // ERROR } + DEBUG("_Cast: Borrow coerce"); this->context.apply_equality(node.span(), *e2.inner, *e.inner); ), (Pointer, if( e.type != e2.type ) { - this->context.apply_equality(node.span(), *e2.inner, *e.inner); + //DEBUG("_Cast: Pointer classes mismatch"); + //this->context.apply_equality(node.span(), *e2.inner, *e.inner); } else { // Nothing @@ -1416,6 +1420,9 @@ namespace typeck { (UfcsKnown, const auto& trait = this->context.m_crate.get_trait_by_path(sp, e.trait.m_path); fix_param_count(sp, this->context, path, trait.m_params, e.trait.m_params); + if( trait.m_values.count(e.item) == 0 ) { + BUG(sp, "Method '" << e.item << "' of trait " << e.trait.m_path << " doesn't exist"); + } const auto& fcn = trait.m_values.at(e.item).as_Function(); fix_param_count(sp, this->context, path, fcn.m_params, e.params); cache.m_fcn_params = &fcn.m_params; diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp index 1b3d45e4..d59de90c 100644 --- a/src/hir_typeck/expr_context.cpp +++ b/src/hir_typeck/expr_context.cpp @@ -1350,8 +1350,36 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR 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 ) - ERROR(sp, E0000, "Can't coerce between trait objects - " << left_inner_res << " and " << right_inner_res); + if( left_inner_res != right_inner_res ) { + const auto& lie = left_inner_res .m_data.as_TraitObject(); + const auto& rie = right_inner_res.m_data.as_TraitObject(); + // 1. Check/equate the main trait (NOTE: Eventualy this may be a set of data traits) + if( lie.m_trait.m_path.m_path != rie.m_trait.m_path.m_path ) { + ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " (trait mismatch)"); + } + equality_typeparams(lie.m_trait.m_path.m_params, rie.m_trait.m_path.m_params); + + // 2. Ensure that the LHS's marker traits are a strict subset of the RHS + // NOTE: This assumes sorting - will false fail if ordering differs + unsigned int r_i = 0; + for(unsigned int l_i = 0; l_i < lie.m_markers.size(); l_i ++) + { + while( r_i < rie.m_markers.size() && rie.m_markers[r_i].m_path != lie.m_markers[l_i].m_path ) { + r_i += 1; + } + if( r_i == rie.m_markers.size() ) { + ERROR(sp, E0000, "Can't coerce between trait objects - " << left_inner_res << " and " << right_inner_res << " (added marker)"); + } + } + // Coercion is possible and valid. + // HACK: Uses _Unsize as a coerce + 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 ; + } // - Equal, nothing to do return ; } @@ -1420,6 +1448,7 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR auto& node_ptr = *node_ptr_ptr; auto span = node_ptr->span(); + node_ptr->m_res_type = r_t.clone(); node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Cast( mv$(span), mv$(node_ptr), l_t.clone() )); node_ptr->m_res_type = l_t.clone(); diff --git a/src/main.cpp b/src/main.cpp index 90358661..85307663 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -203,11 +203,11 @@ int main(int argc, char *argv[]) ::std::cerr << "Parser Error: " << e.what() << ::std::endl;
return 2;
}
- catch(const ::std::exception& e)
- {
- ::std::cerr << "Misc Error: " << e.what() << ::std::endl;
- return 2;
- }
+ //catch(const ::std::exception& e)
+ //{
+ // ::std::cerr << "Misc Error: " << e.what() << ::std::endl;
+ // return 2;
+ //}
//catch(const char* e)
//{
// ::std::cerr << "Internal Compiler Error: " << e << ::std::endl;
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 3e1e2ff4..34255e99 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -645,7 +645,26 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex if( !n.args().is_empty() ) { trait_path.nodes().back().args() = mv$(n.args()); } - auto new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(), mv$(trait_path)); + // TODO: If the named item can't be found in the trait, fall back to it being a type binding + // - What if this item is from a nested trait? + ::AST::Path new_path; + bool found = false; + //switch(mode) + //{ + //case Context::LookupMode::Value: { + assert(i+1 < path_abs.nodes.size()); + auto it = ::std::find_if( e.trait_->items().begin(), e.trait_->items().end(), [&](const auto& x){ return x.name == path_abs.nodes[i+1].name(); } ); + if( it != e.trait_->items().end() ) { + found = true; + } + // } break; + //} + if( !found ) { + new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(sp, mv$(trait_path))); + } + else { + new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(), mv$(trait_path)); + } for( unsigned int j = i+1; j < path_abs.nodes.size(); j ++ ) new_path.nodes().push_back( mv$(path_abs.nodes[j]) ); |