summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp16
-rw-r--r--src/hir_typeck/helpers.cpp93
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;
}