summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-12 17:42:53 +1000
committerJohn Hodge <tpg@mutabah.net>2016-07-12 17:42:53 +1000
commitfa7bc272c17a1fa4401ae3733984e338ff95443b (patch)
tree4ad877c876462ebb571e110f4b6c171a7e9c8014 /src
parenta7fb52b0e1f2a0159a986b25b10241655b56c077 (diff)
downloadmrust-fa7bc272c17a1fa4401ae3733984e338ff95443b.tar.gz
HIR Typecheck - Handle more complex impl bindings
Diffstat (limited to 'src')
-rw-r--r--src/hir/type.cpp14
-rw-r--r--src/hir_typeck/helpers.cpp32
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: