summaryrefslogtreecommitdiff
path: root/src/hir_typeck
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-02-12 16:31:48 +0800
committerJohn Hodge <tpg@mutabah.net>2017-05-05 14:44:18 +0800
commita71ea499fa11c4268c0e85c11c03205c540b2edb (patch)
tree27ca1b5a5cffb395b854531cb826a740f5430275 /src/hir_typeck
parent91e474dcd8df8bf762733d9cc484cf05cc8ef9ea (diff)
downloadmrust-a71ea499fa11c4268c0e85c11c03205c540b2edb.tar.gz
HIR Typecheck Static - Search bounds on trait for associated type bounds
Diffstat (limited to 'src/hir_typeck')
-rw-r--r--src/hir_typeck/static.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index f3b483c9..83299909 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -237,12 +237,11 @@ bool StaticTraitResolve::find_impl(
auto monomorph_cb = monomorphise_type_get_cb(sp, &*pe.type, &pe.trait.m_params, nullptr, nullptr);
- for(const auto& bound : aty_def.m_trait_bounds)
- {
+ auto check_bound = [&](const ::HIR::TraitPath& bound) {
const auto& b_params = bound.m_path.m_params;
::HIR::PathParams params_mono_o;
const auto& b_params_mono = (monomorphise_pathparams_needed(b_params) ? params_mono_o = monomorphise_path_params_with(sp, b_params, monomorph_cb, false) : b_params);
- DEBUG(": " << bound.m_path.m_path << b_params_mono);
+ DEBUG("[find_impl] : " << bound.m_path.m_path << b_params_mono);
if( bound.m_path.m_path == trait_path )
{
@@ -279,9 +278,40 @@ bool StaticTraitResolve::find_impl(
DEBUG("impl " << trait_path << i_params << " for " << type << " -- desired " << trait_path << *trait_params);
return found_cb( ImplRef(type.clone(), i_params.clone(), {}), false );
});
- if( ret )
+ return ret;
+ };
+
+ for(const auto& bound : aty_def.m_trait_bounds)
+ {
+ if( check_bound(bound) )
+ return true;
+ }
+
+ // Check `where` clauses on the trait too
+ for(const auto& bound : trait_ref.m_params.m_bounds)
+ {
+ if( !bound.is_TraitBound() ) continue;
+ const auto& be = bound.as_TraitBound();
+
+ DEBUG("be.type = " << be.type);
+ if( !be.type.m_data.is_Path() )
+ continue;
+ if( !be.type.m_data.as_Path().path.m_data.is_UfcsKnown() )
+ continue ;
+ {
+ const auto& pe2 = be.type.m_data.as_Path().path.m_data.as_UfcsKnown();
+ if( *pe2.type != ::HIR::TypeRef("Self",GENERIC_Self) )
+ continue ;
+ if( pe2.trait.m_path != pe.trait.m_path )
+ continue ;
+ if( pe2.item != pe.item )
+ continue ;
+ }
+
+ if( check_bound(be.trait) )
return true;
}
+
DEBUG("- No bounds matched");
}
)