diff options
author | John Hodge <tpg@mutabah.net> | 2016-07-10 21:05:33 +1000 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-07-10 21:05:33 +1000 |
commit | 0e41a86b8f23c7165e88930af5b9d397f6b5d16c (patch) | |
tree | 04d2f6a7062e1b2d82dff9785b5e3b07f3ca3f33 | |
parent | dc623c66c51f0c2bf1b75e86aaa310b65f456d1b (diff) | |
download | mrust-0e41a86b8f23c7165e88930af5b9d397f6b5d16c.tar.gz |
HIR Typecheck CS - Fix autoderef picking non-methods
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 4 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 70 |
2 files changed, 45 insertions, 29 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 448e2ded..f550f9dc 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1538,7 +1538,7 @@ namespace { void visit(::HIR::ExprNode_CallMethod& node) override { const auto& ty = this->context.get_type(node.m_value->m_res_type); //const auto ty = this->context.m_resolve.expand_associated_types(node.span(), this->context.get_type(node.m_value->m_res_type).clone()); - TRACE_FUNCTION_F("(CallMethod) ty = " << this->context.m_ivars.fmt_type(ty)); + TRACE_FUNCTION_F("(CallMethod) {" << this->context.m_ivars.fmt_type(ty) << "}." << node.m_method); // Make sure that no mentioned types are inferred until this method is known this->context.equate_types_shadow(node.span(), node.m_res_type); @@ -1551,7 +1551,7 @@ namespace { unsigned int deref_count = this->context.m_resolve.autoderef_find_method(node.span(), node.m_traits, ty, node.m_method, fcn_path); if( deref_count != ~0u ) { - DEBUG("- deref_count = " << deref_count); + DEBUG("- deref_count = " << deref_count << ", fcn_path = " << fcn_path); visit_call_populate_cache(this->context, node.span(), fcn_path, node.m_cache); node.m_method_path = mv$(fcn_path); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 691b507e..40011a7a 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -1801,8 +1801,11 @@ bool TraitResolution::trait_contains_method(const Span& sp, const ::HIR::Generic auto it = trait_ptr.m_values.find(name); if( it != trait_ptr.m_values.end() ) { if( it->second.is_Function() ) { - out_path = trait_path.clone(); - return true; + const auto& v = it->second.as_Function(); + if( v.m_args.size() > 0 && v.m_args[0].first.m_binding.m_name == "self" ) { + out_path = trait_path.clone(); + return true; + } } } @@ -1969,13 +1972,16 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait if( it != trait.m_values.end() ) { if( it->second.is_Function() ) { - fcn_path = ::HIR::Path( ::HIR::Path::Data::Data_UfcsKnown({ - box$( ty.clone() ), - e.m_trait.m_path.clone(), - method_name, - {} - }) ); - return true; + const auto& v = it->second.as_Function(); + if( v.m_args.size() > 0 && v.m_args[0].first.m_binding.m_name == "self" ) { + fcn_path = ::HIR::Path( ::HIR::Path::Data::Data_UfcsKnown({ + box$( ty.clone() ), + e.m_trait.m_path.clone(), + method_name, + {} + }) ); + return true; + } } } ) @@ -2018,13 +2024,15 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait 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, - {} - }) ); - return true; + if( it->second.m_args.size() > 0 && it->second.m_args[0].first.m_binding.m_name == "self" ) { + 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, + {} + }) ); + return true; + } } } // 3. Search for trait methods (using currently in-scope traits) @@ -2033,23 +2041,31 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait if( trait_ref.first == nullptr ) break; + //::HIR::GenericPath final_trait_path; + //if( !this->trait_contains_method(sp, *trait_ref.first, *trait_ref.second, method_name, final_trait_path) ) + // continue ; + //DEBUG("- Found trait " << final_trait_path); + // TODO: Search supertraits too auto it = trait_ref.second->m_values.find(method_name); if( it == trait_ref.second->m_values.end() ) continue ; if( !it->second.is_Function() ) continue ; - DEBUG("Search for impl of " << *trait_ref.first); - // TODO: Need a "don't care" marker for the PathParams - if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](const auto&,const auto&,const auto&) { return true; }) ) { - DEBUG("Found trait impl " << *trait_ref.first << " (" /*<< m_ivars.fmt_type(*trait_ref.first)*/ << ") for " << ty << " ("<<m_ivars.fmt_type(ty)<<")"); - fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({ - box$( ty.clone() ), - trait_ref.first->clone(), - method_name, - {} - }) ); - return true; + const auto& v = it->second.as_Function(); + if( v.m_args.size() > 0 && v.m_args[0].first.m_binding.m_name == "self" ) { + DEBUG("Search for impl of " << *trait_ref.first); + // TODO: Need a "don't care" marker for the PathParams + if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](const auto&,const auto&,const auto&) { return true; }) ) { + DEBUG("Found trait impl " << *trait_ref.first << " (" /*<< m_ivars.fmt_type(*trait_ref.first)*/ << ") for " << ty << " ("<<m_ivars.fmt_type(ty)<<")"); + fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({ + box$( ty.clone() ), + trait_ref.first->clone(), + method_name, + {} + }) ); + return true; + } } } } |