summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-01-20 12:43:01 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-01-20 12:43:01 +0800
commitaf1776f7056c967a0f106e7519afd9b2bd2158d9 (patch)
tree3a35c272467d93e65f2d40d541bbf8f8282b8ab8
parent0af7f41208356599ad367a55e089112ebe46929b (diff)
downloadmrust-af1776f7056c967a0f106e7519afd9b2bd2158d9.tar.gz
Typecheck Static - Handle resolution with pre-existing placeholders
-rw-r--r--src/hir_typeck/static.cpp52
1 files changed, 40 insertions, 12 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index de9b6053..457bd44e 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -541,6 +541,8 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
auto cb_ident = [](const auto&ty)->const ::HIR::TypeRef&{return ty;};
TRACE_FUNCTION_F("impl" << impl_params_def.fmt_args() << " " << des_trait_path << impl_trait_params << " for " << impl_type << impl_params_def.fmt_bounds());
+ // TODO: What if `des_trait_params` already has impl placeholders?
+
::std::vector< const ::HIR::TypeRef*> impl_params;
impl_params.resize( impl_params_def.m_types.size() );
@@ -548,6 +550,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
assert( idx < impl_params.size() );
if( ! impl_params[idx] ) {
impl_params[idx] = &ty;
+ DEBUG("[find_impl__check_crate_raw:cb] Set placeholder " << idx << " to " << ty);
return ::HIR::Compare::Equal;
}
else {
@@ -555,15 +558,34 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
}
};
auto match = impl_type.match_test_generics_fuzz(sp, des_type, cb_ident, cb);
+ unsigned base_impl_placeholder_idx = 0;
if( des_trait_params )
{
assert( des_trait_params->m_types.size() == impl_trait_params.m_types.size() );
+ unsigned max_impl_idx = 0;
for( unsigned int i = 0; i < impl_trait_params.m_types.size(); i ++ )
{
const auto& l = impl_trait_params.m_types[i];
const auto& r = des_trait_params->m_types[i];
match &= l.match_test_generics_fuzz(sp, r, cb_ident, cb);
+
+ visit_ty_with(r, [&](const ::HIR::TypeRef& t)->bool {
+ if( t.m_data.is_Generic() && (t.m_data.as_Generic().binding >> 8) == 2 ) {
+ unsigned impl_idx = t.m_data.as_Generic().binding & 0xFF;
+ max_impl_idx = ::std::max(max_impl_idx, impl_idx+1);
+ }
+ return false;
+ });
}
+ base_impl_placeholder_idx = max_impl_idx;
+
+ size_t n_placeholders_needed = 0;
+ for(unsigned int i = 0; i < impl_params.size(); i ++ ) {
+ if( !impl_params[i] ) {
+ n_placeholders_needed ++;
+ }
+ }
+ ASSERT_BUG(sp, base_impl_placeholder_idx + n_placeholders_needed <= 256, "Out of impl placeholders");
}
if( match == ::HIR::Compare::Unequal ) {
DEBUG(" > Type mismatch");
@@ -575,7 +597,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
if( !impl_params[i] ) {
if( placeholders.size() == 0 )
placeholders.resize(impl_params.size());
- placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i);
+ placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i + base_impl_placeholder_idx);
DEBUG("Placeholder " << placeholders[i] << " for " << impl_params_def.m_types[i].m_name);
}
}
@@ -584,19 +606,24 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
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;
- 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("[find_impl__check_crate_raw:cb_match] Bind placeholder " << i << " to " << ty);
- ph = ty.clone();
- return ::HIR::Compare::Equal;
- }
- else if( ph == ty ) {
- return ::HIR::Compare::Equal;
+ if( (idx % 256) >= base_impl_placeholder_idx ) {
+ auto i = idx % 256 - base_impl_placeholder_idx;
+ ASSERT_BUG(sp, !impl_params[i], "Placeholder to populated type returned. new " << ty << ", existing " << *impl_params[i]);
+ auto& ph = placeholders[i];
+ if( ph.m_data.is_Generic() && ph.m_data.as_Generic().binding == idx ) {
+ DEBUG("[find_impl__check_crate_raw:cb_match] Bind placeholder " << i << " to " << ty);
+ ph = ty.clone();
+ return ::HIR::Compare::Equal;
+ }
+ else if( ph == ty ) {
+ return ::HIR::Compare::Equal;
+ }
+ else {
+ TODO(sp, "[find_impl__check_crate_raw:cb_match] Compare placeholder " << i << " " << ph << " == " << ty);
+ }
}
else {
- TODO(sp, "[find_impl__check_crate_raw:cb_match] Compare placeholder " << i << " " << ph << " == " << ty);
+ return ::HIR::Compare::Fuzzy;
}
}
else {
@@ -664,6 +691,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
::HIR::TypeRef have = impl.get_type(aty_name.c_str());
this->expand_associated_types(sp, have);
+ DEBUG("::" << aty_name << " - " << have << " ?= " << exp);
//auto cmp = have .match_test_generics_fuzz(sp, exp, cb_ident, cb_match);
auto cmp = exp .match_test_generics_fuzz(sp, have, cb_ident, cb_match);
if( cmp == ::HIR::Compare::Unequal )