diff options
Diffstat (limited to 'src/hir')
-rw-r--r-- | src/hir/hir.cpp | 30 | ||||
-rw-r--r-- | src/hir/path.hpp | 2 | ||||
-rw-r--r-- | src/hir/type.cpp | 9 |
3 files changed, 29 insertions, 12 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 5b43c1c9..b913c4e3 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -132,9 +132,10 @@ namespace { // TODO: What indicates what out of ty_res? - if( right.m_data.is_Infer() ) { + if( const auto* re = right.m_data.opt_Infer() ) + { //DEBUG("left = " << left << ", right = " << right); - switch(right.m_data.as_Infer().ty_class) + switch(re->ty_class) { case ::HIR::InferClass::None: case ::HIR::InferClass::Diverge: @@ -162,20 +163,30 @@ namespace { // A local generic could match anything, leave that up to the caller if( left.m_data.is_Generic() ) { + DEBUG("> Generic left, success"); return true; } // A local UfcsKnown can only be becuase it couldn't be expanded earlier, assume it could match if( left.m_data.is_Path() && left.m_data.as_Path().path.m_data.is_UfcsKnown() ) { // True? + //DEBUG("> UFCS Unknown left, success"); return true; } // If the RHS (provided) is generic, it can only match if it binds to a local type parameter if( right.m_data.is_Generic() ) { + // TODO: This is handled above? + //DEBUG("> Generic right, only if left generic"); return left.m_data.is_Generic(); } + // If the RHS (provided) is generic, it can only match if it binds to a local type parameter + if( TU_TEST1(right.m_data, Path, .binding.is_Unbound()) ) { + //DEBUG("> UFCS Unknown right, fuzzy"); + return true; + } if( left.m_data.tag() != right.m_data.tag() ) { + //DEBUG("> Tag mismatch, failure"); return false; } TU_MATCH(::HIR::TypeRef::Data, (left.m_data, right.m_data), (le, re), @@ -272,7 +283,9 @@ namespace { return false; } - if( left.m_params.m_types.size() > 0 || right.m_params.m_types.size() > 0 ) { + if( left.m_params.m_types.size() > 0 || right.m_params.m_types.size() > 0 ) + { + // Count mismatch. Allow due to defaults. if( left.m_params.m_types.size() != right.m_params.m_types.size() ) { return true; //TODO(Span(), "Match generic paths " << left << " and " << right << " - count mismatch"); @@ -318,21 +331,22 @@ namespace { bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { // NOTE: Don't return any impls when the type is an unbouned ivar. Wouldn't be able to pick anything anyway - if( is_unbounded_infer(type) ) { + // TODO: For `Unbound`, it could be valid, if the target is a generic. + if( is_unbounded_infer(type) || TU_TEST1(type.m_data, Path, .binding.is_Unbound()) ) { return false; } 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 { - if( is_unbounded_infer(type) ) { + if( is_unbounded_infer(type) || TU_TEST1(type.m_data, Path, .binding.is_Unbound()) ) { return false; } 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 { - if( is_unbounded_infer(type) ) { + if( is_unbounded_infer(type) || TU_TEST1(type.m_data, Path, .binding.is_Unbound()) ) { return false; } return matches_type_int(m_params, m_type, type, ty_res, true); @@ -807,7 +821,7 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& auto cb_ident = [](const ::HIR::TypeRef& x)->const ::HIR::TypeRef& { return x; }; bool is_reversed = false; ::std::vector<const ::HIR::TypeRef*> impl_tys; - auto cb_match = [&](unsigned int idx, const ::HIR::TypeRef& x)->::HIR::Compare { + auto cb_match = [&](unsigned int idx, const auto& /*name*/, const ::HIR::TypeRef& x)->::HIR::Compare { assert(idx < impl_tys.size()); if( impl_tys.at(idx) ) { @@ -943,7 +957,7 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& ::std::vector<const ::HIR::TypeRef*> impl_tys { ti.m_params.m_types.size() }; auto cb_ident = [](const ::HIR::TypeRef& x)->const ::HIR::TypeRef& { return x; }; - auto cb_match = [&](unsigned int idx, const ::HIR::TypeRef& x)->::HIR::Compare { + auto cb_match = [&](unsigned int idx, const auto& /*name*/, const ::HIR::TypeRef& x)->::HIR::Compare { assert(idx < impl_tys.size()); if( impl_tys.at(idx) ) { diff --git a/src/hir/path.hpp b/src/hir/path.hpp index 12e32dd1..7734b657 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -25,7 +25,7 @@ enum Compare { }; typedef ::std::function<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> t_cb_resolve_type; -typedef ::std::function< ::HIR::Compare(unsigned int, const ::HIR::TypeRef&) > t_cb_match_generics; +typedef ::std::function< ::HIR::Compare(unsigned int, const ::std::string&, const ::HIR::TypeRef&) > t_cb_match_generics; static inline ::std::ostream& operator<<(::std::ostream& os, const Compare& x) { switch(x) diff --git a/src/hir/type.cpp b/src/hir/type.cpp index c672b3bd..36f09c9c 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -482,11 +482,12 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x } ::HIR::Compare HIR::TypeRef::match_test_generics_fuzz(const Span& sp, const ::HIR::TypeRef& x_in, t_cb_resolve_type resolve_placeholder, t_cb_match_generics callback) const { - if( m_data.is_Generic() ) { - return callback(m_data.as_Generic().binding, x_in); + if( const auto* e = m_data.opt_Generic() ) { + return callback(e->binding, e->name, x_in); } const auto& v = (this->m_data.is_Infer() ? resolve_placeholder(*this) : *this); const auto& x = (x_in.m_data.is_Infer() || x_in.m_data.is_Generic() ? resolve_placeholder(x_in) : x_in); + TRACE_FUNCTION_F(*this << ", " << x_in << " -- " << v << ", " << x); // If `x` is an ivar - This can be a fuzzy match. TU_IFLET(::HIR::TypeRef::Data, x.m_data, Infer, xe, // - If type inferrence is active (i.e. this ivar has an index), AND both `v` and `x` refer to the same ivar slot @@ -714,7 +715,9 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x return cmp; ), (ErasedType, - TODO(sp, "ErasedType - match_test_generics_fuzz - " << v << " -- " << x); + if( te.m_origin != xe.m_origin ) + return Compare::Unequal; + return Compare::Equal; ), (Array, if( te.size_val != xe.size_val ) { |