summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_typeck/helpers.cpp34
-rw-r--r--src/hir_typeck/helpers.hpp1
2 files changed, 30 insertions, 5 deletions
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 57552583..6ad2a314 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -2825,11 +2825,21 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa
}
),
(Generic,
+ // TODO: Store this result - or even pre-calculate it.
const auto& lang_Copy = this->m_crate.get_lang_item_path(sp, "copy");
return this->iterate_bounds([&](const auto& b) {
TU_IFLET(::HIR::GenericBound, b, TraitBound, be,
- if(be.type == ty && be.trait.m_path == lang_Copy ) {
- return true;
+ if(be.type == ty)
+ {
+ if(be.trait.m_path == lang_Copy)
+ return true;
+ ::HIR::PathParams pp;
+ bool rv = this->find_named_trait_in_trait(sp,
+ lang_Copy,pp, *be.trait.m_trait_ptr, be.trait.m_path.m_path, be.trait.m_path.m_params, type,
+ [&](const auto& , const auto&, const auto&) { return true; }
+ );
+ if(rv)
+ return true;
}
)
return false;
@@ -3028,13 +3038,25 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
ERROR(sp, E0000, "Could not find method `" << method_name << "` on type `" << top_ty << "`");
}
+::std::ostream& operator<<(::std::ostream& os, const TraitResolution::AllowedReceivers& x)
+{
+ switch(x)
+ {
+ case TraitResolution::AllowedReceivers::All: os << "All"; break;
+ case TraitResolution::AllowedReceivers::AnyBorrow: os << "AnyBorrow"; break;
+ case TraitResolution::AllowedReceivers::Value: os << "Value"; break;
+ case TraitResolution::AllowedReceivers::Box: os << "Box"; break;
+ }
+ return os;
+}
+
bool TraitResolution::find_method(
const Span& sp,
const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars,
const ::HIR::TypeRef& ty, const ::std::string& method_name, AllowedReceivers ar,
/* Out -> */::HIR::Path& fcn_path) const
{
- TRACE_FUNCTION_F("ty=" << ty << ", name=" << method_name);
+ TRACE_FUNCTION_F("ty=" << ty << ", name=" << method_name << ", ar=" << ar);
// 1. Search generic bounds for a match
const ::HIR::GenericParams* v[2] = { m_item_params, m_impl_params };
for(auto p : v)
@@ -3048,11 +3070,13 @@ bool TraitResolution::find_method(
continue ;
// - Bound's type matches, check if the bounded trait has the method we're searching for
- DEBUG("Bound `" << e.type << " : " << e.trait.m_path << "` - Matches " << ty);
+ DEBUG("Bound `" << e.type << " : " << e.trait.m_path << "` - Type match " << ty);
::HIR::GenericPath final_trait_path;
assert(e.trait.m_trait_ptr);
- if( !this->trait_contains_method(sp, e.trait.m_path, *e.trait.m_trait_ptr, ty, method_name, ar, final_trait_path) )
+ if( !this->trait_contains_method(sp, e.trait.m_path, *e.trait.m_trait_ptr, ty, method_name, ar, final_trait_path) ) {
+ DEBUG("- Method '" << method_name << "' missing");
continue ;
+ }
DEBUG("- Found trait " << final_trait_path);
// TODO: Re-monomorphise final trait using `ty`?
// - Could collide with legitimate uses of `Self`
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index a2a08ca2..76487140 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -237,6 +237,7 @@ public:
Value,
Box,
};
+ friend ::std::ostream& operator<<(::std::ostream& os, const AllowedReceivers& x);
bool find_method(const Span& sp, const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& ty, const ::std::string& method_name, AllowedReceivers ar, /* Out -> */::HIR::Path& fcn_path) const;
/// Locates a named method in a trait, and returns the path of the trait that contains it (with fixed parameters)