diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-09-20 22:33:02 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-09-20 22:33:02 +0800 |
commit | 48c1c9a23f3ac0e48bdf230873ea8723a0e44480 (patch) | |
tree | 1769a75cbb285d74b24570ca497743393ed396f6 | |
parent | aa50a9c9d1628670d37c07f3d5f60a751c2898fa (diff) | |
download | mrust-48c1c9a23f3ac0e48bdf230873ea8723a0e44480.tar.gz |
HIR Typecheck - Revert change to method lookup order, plan for fallbacks
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 16 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 93 |
2 files changed, 64 insertions, 45 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 61f2b568..226be96c 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2606,7 +2606,12 @@ namespace { // Using autoderef, locate this method on the type ::HIR::Path fcn_path { ::HIR::SimplePath() }; TraitResolution::AutoderefBorrow ad_borrow; + // TODO: Obtain a list of avaliable methods at that level? + // - If running in a mode after stablise (before defaults), fall + // back to trait if the inherent is still ambigious. unsigned int deref_count = this->context.m_resolve.autoderef_find_method(node.span(), node.m_traits, node.m_trait_param_ivars, ty, node.m_method, fcn_path, ad_borrow); + //::std::vector<::std::pair<TraitResolution::AutoderefBorrow, ::HIR::Path>> possible_methods; + //unsigned int deref_count = this->context.m_resolve.autoderef_find_method(node.span(), node.m_traits, node.m_trait_param_ivars, ty, node.m_method, possible_methods); if( deref_count != ~0u ) { DEBUG("- deref_count = " << deref_count << ", fcn_path = " << fcn_path); @@ -2629,6 +2634,17 @@ namespace { ) if( !visit_call_populate_cache(this->context, node.span(), node.m_method_path, node.m_cache) ) { DEBUG("- AMBIGUOUS - Trying again later"); + // Move the params back + TU_MATCH(::HIR::Path::Data, (node.m_method_path.m_data), (e), + (Generic, ), + (UfcsUnknown, ), + (UfcsKnown, + node.m_params = mv$(e.params); + ), + (UfcsInherent, + node.m_params = mv$(e.params); + ) + ) return ; } DEBUG("> m_method_path = " << node.m_method_path); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 6627a39a..94f7304d 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -3465,6 +3465,8 @@ const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::Ty } } } + +//unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, /* Out -> */::std::vector<AutoderefBorrow,::HIR::Path>& possibilities) const unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, /* Out -> */::HIR::Path& fcn_path, AutoderefBorrow& borrow) const { TRACE_FUNCTION_F("{" << top_ty << "}." << method_name); @@ -3501,7 +3503,7 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t if( ty.m_data.is_Borrow() && should_pause( this->m_ivars.get_type(*ty.m_data.as_Borrow().inner) ) ) { return ~0u; } - // TODO: Pause on Box<_> + // TODO: Pause on Box<_>? DEBUG(deref_count << ": " << ty); // Non-referenced @@ -3897,7 +3899,51 @@ bool TraitResolution::find_method( { } - // 4. Search for trait methods (using currently in-scope traits) + // 4. Search for inherent methods + // - Inherent methods are searched first. + DEBUG("> Inherent methods"); + { + const ::HIR::TypeRef* cur_check_ty = &ty; + auto find_type_impls_cb = [&](const auto& impl) { + // TODO: Should this take into account the actual suitability of this method? Or just that the name exists? + // - If this impl matches fuzzily, it may not actually match + auto it = impl.m_methods.find( method_name ); + if( it == impl.m_methods.end() ) + return false ; + const ::HIR::Function& fcn = it->second.data; + if( const auto* self_ty_p = this->check_method_receiver(sp, fcn.m_receiver, ty, access) ) + { + DEBUG("Found `impl" << impl.m_params.fmt_args() << " " << impl.m_type << "` fn " << method_name/* << " - " << top_ty*/); + if( *self_ty_p == *cur_check_ty ) + { + fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsInherent({ + box$(self_ty_p->clone()), + method_name, + {} + }) ); + return true; + } + } + DEBUG("[find_method] Method was present in `impl" << impl.m_params.fmt_args() << " " << impl.m_type << "` but receiver mismatched"); + return false; + }; + if( m_crate.find_type_impls(ty, m_ivars.callback_resolve_infer(), find_type_impls_cb) ) + { + return true; + } + cur_check_ty = (ty.m_data.is_Borrow() ? &*ty.m_data.as_Borrow().inner : nullptr); + if( cur_check_ty && m_crate.find_type_impls(*cur_check_ty, m_ivars.callback_resolve_infer(), find_type_impls_cb) ) + { + return true; + } + cur_check_ty = this->type_is_owned_box(sp, ty); + if( cur_check_ty && m_crate.find_type_impls(*cur_check_ty, m_ivars.callback_resolve_infer(), find_type_impls_cb) ) + { + return true; + } + } + + // 5. Search for trait methods (using currently in-scope traits) DEBUG("> Trait methods"); for(const auto& trait_ref : ::reverse(traits)) { @@ -3945,49 +3991,6 @@ bool TraitResolution::find_method( } } - // 5. Search for inherent methods - DEBUG("> Inherent methods"); - { - const ::HIR::TypeRef* cur_check_ty = &ty; - auto find_type_impls_cb = [&](const auto& impl) { - // TODO: Should this take into account the actual suitability of this method? Or just that the name exists? - // - If this impl matches fuzzily, it may not actually match - auto it = impl.m_methods.find( method_name ); - if( it == impl.m_methods.end() ) - return false ; - const ::HIR::Function& fcn = it->second.data; - if( const auto* self_ty_p = this->check_method_receiver(sp, fcn.m_receiver, ty, access) ) - { - DEBUG("Found `impl" << impl.m_params.fmt_args() << " " << impl.m_type << "` fn " << method_name/* << " - " << top_ty*/); - if( *self_ty_p == *cur_check_ty ) - { - fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsInherent({ - box$(self_ty_p->clone()), - method_name, - {} - }) ); - return true; - } - } - DEBUG("[find_method] Method was present in `impl" << impl.m_params.fmt_args() << " " << impl.m_type << "` but receiver mismatched"); - return false; - }; - if( m_crate.find_type_impls(ty, m_ivars.callback_resolve_infer(), find_type_impls_cb) ) - { - return true; - } - cur_check_ty = (ty.m_data.is_Borrow() ? &*ty.m_data.as_Borrow().inner : nullptr); - if( cur_check_ty && m_crate.find_type_impls(*cur_check_ty, m_ivars.callback_resolve_infer(), find_type_impls_cb) ) - { - return true; - } - cur_check_ty = this->type_is_owned_box(sp, ty); - if( cur_check_ty && m_crate.find_type_impls(*cur_check_ty, m_ivars.callback_resolve_infer(), find_type_impls_cb) ) - { - return true; - } - } - return false; } |