summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-30 11:31:06 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-30 11:31:06 +0800
commita902e15959dfb92c3e6012c9a2352a055397916d (patch)
tree7325c18b699a09dfafaa8b6d1ae4f6cc5baeb11f
parentcd39d62cbe37580307c3aff7aaa5c3644d5f2050 (diff)
downloadmrust-a902e15959dfb92c3e6012c9a2352a055397916d.tar.gz
HIR Typecheck Expr - Handle positive impls for auto traits
-rw-r--r--src/hir_typeck/helpers.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index ffb2d785..cc580a58 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1914,14 +1914,42 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
// - Search for positive impls for this type
DEBUG("- Search positive impls");
- bool positive_found = this->m_crate.find_auto_trait_impls(trait, type, this->m_ivars.callback_resolve_infer(),
+ bool positive_found = false;
+ this->m_crate.find_auto_trait_impls(trait, type, this->m_ivars.callback_resolve_infer(),
[&](const auto& impl) {
// Skip any negative impls on this pass
if( impl.is_positive != true )
return false;
- // TODO: Perform parameter and bound checks.
- TODO(sp, "[find_trait_impls_crate] Matching positive "
- << "- impl" << impl.m_params.fmt_args() << " " << trait << impl.m_trait_args << " for " << impl.m_type << impl.m_params.fmt_bounds());
+
+ DEBUG("[find_trait_impls_crate] - Auto Pos Found impl" << impl.m_params.fmt_args() << " " << trait << impl.m_trait_args << " for " << impl.m_type << " " << impl.m_params.fmt_bounds());
+
+ // Compare with `params`
+ ::std::vector< const ::HIR::TypeRef*> impl_params;
+ ::std::vector< ::HIR::TypeRef> placeholders;
+ auto match = this->ftic_check_params(sp, trait, params_ptr, type, impl.m_params, impl.m_trait_args, impl.m_type, impl_params, placeholders);
+ if( match == ::HIR::Compare::Unequal ) {
+ // If any bound failed, return false (continue searching)
+ return false;
+ }
+
+ auto monomorph = [&](const auto& gt)->const auto& {
+ const auto& ge = gt.m_data.as_Generic();
+ ASSERT_BUG(sp, ge.binding >> 8 != 2, "");
+ assert( ge.binding < impl_params.size() );
+ if( !impl_params[ge.binding] ) {
+ return placeholders[ge.binding];
+ }
+ return *impl_params[ge.binding];
+ };
+ // TODO: Ensure that there are no-longer any magic params?
+
+ auto ty_mono = monomorphise_type_with(sp, impl.m_type, monomorph, false);
+ auto args_mono = monomorphise_path_params_with(sp, impl.m_trait_args, monomorph, false);
+ // NOTE: Auto traits can't have items, so no associated types
+
+ positive_found = true;
+ DEBUG("[find_trait_impls_crate] Auto Positive callback(args=" << args_mono << ")");
+ return callback(ImplRef(mv$(ty_mono), mv$(args_mono), {}), match);
});
if( positive_found ) {
// A positive impl was found, so return true (callback should have been called)
@@ -2099,6 +2127,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
return false;
}
+ #if 0
auto monomorph = [&](const auto& gt)->const auto& {
const auto& ge = gt.m_data.as_Generic();
ASSERT_BUG(sp, ge.binding >> 8 != 2, "");
@@ -2123,6 +2152,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
// TODO: Ensure that there are no-longer any magic params?
DEBUG("[find_trait_impls_crate] callback(args=" << args_mono << ", assoc={" << types << "})");
+ #endif
return callback(ImplRef(mv$(impl_params), trait, impl, mv$(placeholders)), match);
}
);