diff options
author | John Hodge <tpg@mutabah.net> | 2016-07-12 17:42:53 +1000 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-07-12 17:42:53 +1000 |
commit | fa7bc272c17a1fa4401ae3733984e338ff95443b (patch) | |
tree | 4ad877c876462ebb571e110f4b6c171a7e9c8014 /src | |
parent | a7fb52b0e1f2a0159a986b25b10241655b56c077 (diff) | |
download | mrust-fa7bc272c17a1fa4401ae3733984e338ff95443b.tar.gz |
HIR Typecheck - Handle more complex impl bindings
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/type.cpp | 14 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 32 |
2 files changed, 25 insertions, 21 deletions
diff --git a/src/hir/type.cpp b/src/hir/type.cpp index ae49f3db..46ecf229 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -297,12 +297,10 @@ 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_Infer() ) { - BUG(sp, "Encountered '_' as this - " << *this); - } if( m_data.is_Generic() ) { return callback(m_data.as_Generic().binding, 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); TU_IFLET(::HIR::TypeRef::Data, x.m_data, Infer, xe, switch(xe.ty_class) @@ -312,7 +310,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x //return true; return Compare::Fuzzy; case ::HIR::InferClass::Integer: - TU_IFLET(::HIR::TypeRef::Data, m_data, Primitive, te, + TU_IFLET(::HIR::TypeRef::Data, v.m_data, Primitive, te, switch(te) { case ::HIR::CoreType::I8: case ::HIR::CoreType::U8: @@ -329,7 +327,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x ) break; case ::HIR::InferClass::Float: - TU_IFLET(::HIR::TypeRef::Data, m_data, Primitive, te, + TU_IFLET(::HIR::TypeRef::Data, v.m_data, Primitive, te, switch(te) { case ::HIR::CoreType::F32: @@ -344,11 +342,11 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x break; } ) - if( m_data.tag() != x.m_data.tag() ) { - DEBUG("- Tag mismatch " << *this << " and " << x); + if( v.m_data.tag() != x.m_data.tag() ) { + DEBUG("- Tag mismatch " << v << " and " << x); return Compare::Unequal; } - TU_MATCH(::HIR::TypeRef::Data, (m_data, x.m_data), (te, xe), + TU_MATCH(::HIR::TypeRef::Data, (v.m_data, x.m_data), (te, xe), (Infer, throw "";), (Generic, throw "";), (Primitive, diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 71fb5b2c..6f022f68 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -1721,37 +1721,44 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, if( !impl_params[i] ) { if( placeholders.size() == 0 ) placeholders.resize(impl_params.size()); - placeholders[i] = ::HIR::TypeRef("impl_?", i); + placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i); } } - #if 0 - auto cb_infer = [&](const auto& ty) { + auto cb_infer = [&](const auto& ty)->const auto& { if( ty.m_data.is_Infer() ) return this->m_ivars.get_type(ty); - else if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding >> 8 == 2 ) // Generic group 2 = Placeholders + else if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding >> 8 == 2 ) { // Generic group 2 = Placeholders unsigned int i = ty.m_data.as_Generic().binding % 256; TODO(sp, "Obtain placeholder " << i); + } else return ty; }; auto cb_match = [&](unsigned int idx, const auto& ty) { + if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding == idx ) + return ::HIR::Compare::Equal; if( idx >> 8 == 2 ) { auto i = idx % 256; - TODO(sp, "Compare/bind placeholder " << i); + ASSERT_BUG(sp, !impl_params[i], "Placeholder to populated type returned"); + auto& ph = placeholders[i]; + if( ph.m_data.is_Generic() && ph.m_data.as_Generic().binding == idx ) { + DEBUG("Bind placeholder " << i << " to " << ty); + ph = ty.clone(); + return ::HIR::Compare::Equal; + } + else { + TODO(sp, "Compare placeholder " << i << " " << ph << " == " << ty); + } } else { - if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding == idx ) - return ::HIR::Compare::Equal; - else - return ::HIR::Compare::Unequal; + return ::HIR::Compare::Unequal; } }; - #endif auto monomorph = [&](const auto& gt)->const auto& { const auto& ge = gt.m_data.as_Generic(); assert( ge.binding < impl_params.size() ); if( !impl_params[ge.binding] ) { - BUG(sp, "Param " << ge.binding << " for `impl" << impl.m_params.fmt_args() << " " << trait << impl.m_trait_args << " for " << impl.m_type << "` wasn't constrained"); + //BUG(sp, "Param " << ge.binding << " for `impl" << impl.m_params.fmt_args() << " " << trait << impl.m_trait_args << " for " << impl.m_type << "` wasn't constrained"); return placeholders[ge.binding]; } return *impl_params[ge.binding]; @@ -1796,8 +1803,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, } const auto& ty = *ty_p; DEBUG(" - Compare " << ty << " and " << assoc_bound.second << ", matching generics"); - auto cmp = assoc_bound.second .compare_with_placeholders(sp, ty, this->m_ivars.callback_resolve_infer()); - //auto cmp = assoc_bound.second .match_test_generics_fuzz(sp, ty, cb_infer, cb_match); + auto cmp = assoc_bound.second .match_test_generics_fuzz(sp, ty, cb_infer, cb_match); switch(cmp) { case ::HIR::Compare::Equal: |