diff options
-rw-r--r-- | src/hir/hir.cpp | 24 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 34 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 11 |
3 files changed, 39 insertions, 30 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 742a2edf..818b7b28 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -30,10 +30,12 @@ namespace HIR { } namespace { - bool matches_type_int(const ::HIR::GenericParams& params, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res) + bool matches_type_int(const ::HIR::GenericParams& params, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) { assert(! left.m_data.is_Infer() ); - const auto& right = (right_in.m_data.is_Infer() || right_in.m_data.is_Generic() ? ty_res(right_in) : right_in); + const auto& right = (right_in.m_data.is_Infer() || right_in.m_data.is_Generic() == expand_generic ? ty_res(right_in) : right_in); + if( right_in.m_data.is_Generic() ) + expand_generic = false; //DEBUG("left = " << left << ", right = " << right); @@ -85,7 +87,7 @@ namespace { } for( unsigned int i = 0; i < pre.m_params.m_types.size(); i ++ ) { - if( ! matches_type_int(params, ple.m_params.m_types[i], pre.m_params.m_types[i], ty_res) ) + if( ! matches_type_int(params, ple.m_params.m_types[i], pre.m_params.m_types[i], ty_res, expand_generic) ) return false; } } @@ -101,32 +103,32 @@ namespace { return false; ), (Array, - if( ! matches_type_int(params, *le.inner, *re.inner, ty_res) ) + if( ! matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic) ) return false; if( le.size_val != re.size_val ) return false; return true; ), (Slice, - return matches_type_int(params, *le.inner, *re.inner, ty_res); + return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic); ), (Tuple, if( le.size() != re.size() ) return false; for( unsigned int i = 0; i < le.size(); i ++ ) - if( !matches_type_int(params, le[i], re[i], ty_res) ) + if( !matches_type_int(params, le[i], re[i], ty_res, expand_generic) ) return false; return true; ), (Borrow, if( le.type != re.type ) return false; - return matches_type_int(params, *le.inner, *re.inner, ty_res); + return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic); ), (Pointer, if( le.type != re.type ) return false; - return matches_type_int(params, *le.inner, *re.inner, ty_res); + return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic); ), (Function, DEBUG("TODO: Compare " << left << " and " << right); @@ -143,15 +145,15 @@ namespace { bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { - return matches_type_int(m_params, m_type, type, ty_res); + return matches_type_int(m_params, m_type, type, ty_res, true); } bool ::HIR::TypeImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { - return matches_type_int(m_params, m_type, type, ty_res); + return matches_type_int(m_params, m_type, type, ty_res, true); } bool ::HIR::MarkerImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { - return matches_type_int(m_params, m_type, type, ty_res); + return matches_type_int(m_params, m_type, type, ty_res, true); } diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index 667129bc..d677dfea 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -262,14 +262,7 @@ namespace typeck { ::HIR::ExprVisitorDef::visit(node); if( node.m_nodes.size() > 0 ) { auto& ln = *node.m_nodes.back(); - // If the child node didn't set a real return type, force it to be the same as this node's - if( ln.m_res_type.m_data.is_Infer() ) { - ln.m_res_type = node.m_res_type.clone(); - } - else { - // If it was set, equate with possiblity of coercion - this->context.apply_equality(ln.span(), node.m_res_type, ln.m_res_type, &node.m_nodes.back()); - } + this->context.apply_equality(ln.span(), node.m_res_type, ln.m_res_type, &node.m_nodes.back()); } else { node.m_res_type = ::HIR::TypeRef::new_unit(); @@ -351,13 +344,7 @@ namespace typeck { types.push_back( sn->m_res_type.clone() ); auto tup_type = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Tuple(mv$(types)) ); - //if( node.m_res_type.m_data.is_Infer() ) - //{ - // node.m_res_type = mv$(tup_type); - //} - //else { - this->context.apply_equality(node.span(), node.m_res_type, tup_type); - //} + this->context.apply_equality(node.span(), node.m_res_type, tup_type); } void visit(::HIR::ExprNode_Closure& node) override { @@ -370,9 +357,16 @@ namespace typeck { ty_data.m_arg_types.push_back( a.second.clone() ); } this->context.add_ivars(node.m_return); + ty_data.m_rettype = box$( node.m_return.clone() ); - node.m_code->m_res_type = node.m_return.clone(); + if( node.m_code->m_res_type == ::HIR::TypeRef() ) { + node.m_code->m_res_type = node.m_return.clone(); + } + else { + this->context.add_ivars( node.m_code->m_res_type ); + this->context.apply_equality( node.span(), node.m_code->m_res_type, node.m_return ); + } this->context.apply_equality( node.span(), node.m_res_type, ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Closure(mv$(ty_data)) ) ); @@ -1107,6 +1101,9 @@ namespace typeck { return ty; }, [&](const auto& impl) { + DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type); + for(const auto& v : impl.m_methods) + DEBUG(" > " << v.first); auto it = impl.m_methods.find(e.item); if( it == impl.m_methods.end() ) return false; @@ -1444,7 +1441,10 @@ namespace typeck { void visit(::HIR::ExprNode_Tuple& node) override { auto& ty = this->context.get_type(node.m_res_type); - assert( ty.m_data.is_Tuple() ); + if( !ty.m_data.is_Tuple() ) { + this->context.dump(); + BUG(node.span(), "Return type of tuple literal wasn't a tuple - " << node.m_res_type << " = " << ty); + } auto& tup_ents = ty.m_data.as_Tuple(); assert( tup_ents.size() == node.m_vals.size() ); diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp index da8e81b8..d69642c9 100644 --- a/src/hir_typeck/expr_context.cpp +++ b/src/hir_typeck/expr_context.cpp @@ -1154,11 +1154,14 @@ bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait, //TODO(sp, "Look up 'Self' in expand_associated_types::expand_placeholder (" << *e2.type << ")"); return *e2.type; } - else { + else if( e.binding < 256 ) { assert(e.binding < impl_args.size()); assert( impl_args[e.binding] ); return *impl_args[e.binding]; } + else { + BUG(sp, "Encountered fn-level params? " << ty); + } ) else return ty; @@ -1169,6 +1172,7 @@ bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait, ( ), (TraitBound, + DEBUG("- Checking bound - " << be.type << " : " << be.trait.m_path); if( !this->check_trait_bound(sp, be.type, be.trait.m_path, expand_placeholder) ) { return false; @@ -1418,7 +1422,10 @@ unsigned int typeck::TypecheckContext::autoderef_find_method(const Span& sp, con for(const auto& impl : m_crate.m_type_impls) { if( impl.matches_type(ty) ) { - DEBUG("Mactching impl " << impl.m_type); + auto it = impl.m_methods.find( method_name ); + if( it == impl.m_methods.end() ) + continue ; + DEBUG("Matching `impl" << impl.m_params.fmt_args() << " " << impl.m_type << "` - " << top_ty); fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsInherent({ box$(ty.clone()), method_name, |