summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-03 13:45:47 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-03 13:45:47 +0800
commit16e7559bcca93b885bc0d2480a388960104bf78e (patch)
tree76f5d07d9a86c7c4932bcc7cce71d0c8c1c4d3ca
parentc621ce63d46c6902d26ffe246295da9303143a39 (diff)
downloadmrust-16e7559bcca93b885bc0d2480a388960104bf78e.tar.gz
Trans Enumerate - Handle places where monomorph lead to dynamic dispatch
-rw-r--r--src/hir_typeck/static.cpp55
-rw-r--r--src/trans/enumerate.cpp51
2 files changed, 57 insertions, 49 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index 243690ce..f60414b2 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -498,12 +498,12 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
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);
+ DEBUG("[find_impl__check_crate_raw:cb_match] Bind placeholder " << i << " to " << ty);
ph = ty.clone();
return ::HIR::Compare::Equal;
}
else {
- TODO(sp, "Compare placeholder " << i << " " << ph << " == " << ty);
+ TODO(sp, "[find_impl__check_crate_raw:cb_match] Compare placeholder " << i << " " << ph << " == " << ty);
}
}
else {
@@ -556,6 +556,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
bool rv = false;
if( b_ty_mono.m_data.is_Generic() && (b_ty_mono.m_data.as_Generic().binding >> 8) == 2 ) {
+ DEBUG("- Placeholder param " << b_ty_mono << ", magic success");
rv = true;
}
else {
@@ -575,41 +576,21 @@ bool StaticTraitResolve::find_impl__check_crate_raw(
}
}
}
-
- bool rv = false;
- if( b_ty_mono.m_data.is_Generic() && (b_ty_mono.m_data.as_Generic().binding >> 8) == 2 ) {
- rv = true;
- }
- else {
- rv = this->find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) {
- //if( fuzzy ) {
- // DEBUG("[find_impl__check_bound] - Fuzzy in bound");
- // return false;
- //}
-
- #if 0
- for(const auto& assoc_bound : b_tp_mono.m_type_bounds) {
- const char* name = assoc_bound.first.c_str();
- const ::HIR::TypeRef& exp = assoc_bound.second;
- ::HIR::TypeRef have = impl.get_type(name);
- // TODO: Returning `_` means unset associated type, should that still be compared?
- if( have != ::HIR::TypeRef() )
- {
- auto cmp = have .match_test_generics_fuzz(sp, exp, cb_ident, cb_match);
- ASSERT_BUG(sp, cmp == ::HIR::Compare::Equal, "Assoc ty " << name << " mismatch, " << have << " != des " << exp);
- }
- else
- {
- DEBUG("Assoc `" << name << "` unbound, can't compare with " << exp);
- }
- }
- #endif
- return true;
- });
- }
- if( !rv ) {
- DEBUG("> Fail - " << b_ty_mono << ": " << b_tp_mono);
- return false;
+ else
+ {
+ bool rv = false;
+ if( b_ty_mono.m_data.is_Generic() && (b_ty_mono.m_data.as_Generic().binding >> 8) == 2 ) {
+ rv = true;
+ }
+ else {
+ rv = this->find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) {
+ return true;
+ });
+ }
+ if( !rv ) {
+ DEBUG("> Fail - " << b_ty_mono << ": " << b_tp_mono);
+ return false;
+ }
}
)
)
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 97e510de..7dab15eb 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -186,13 +186,20 @@ namespace {
return EntPtr::make_VTable({});
}
- ::std::vector<const ::HIR::TypeRef*> best_impl_params;
+ bool is_dynamic = false;
+ ::std::vector<::HIR::TypeRef> best_impl_params;
const ::HIR::TraitImpl* best_impl = nullptr;
resolve.find_impl(sp, e.trait.m_path, e.trait.m_params, *e.type, [&](auto impl_ref, auto is_fuzz) {
DEBUG("Found " << impl_ref);
//ASSERT_BUG(sp, !is_fuzz, "Fuzzy match not allowed here");
- ASSERT_BUG(sp, impl_ref.m_data.is_TraitImpl(), "Trans impl search found an invalid impl type");
- const auto& impl = *impl_ref.m_data.as_TraitImpl().impl;
+ if( ! impl_ref.m_data.is_TraitImpl() ) {
+ DEBUG("Trans impl search found an invalid impl type");
+ is_dynamic = true;
+ // TODO: This can only really happen if it's a trait object magic impl, which should become a vtable lookup.
+ return true;
+ }
+ const auto& impl_ref_e = impl_ref.m_data.as_TraitImpl();
+ const auto& impl = *impl_ref_e.impl;
ASSERT_BUG(sp, impl.m_trait_args.m_types.size() == e.trait.m_params.m_types.size(), "Trait parameter count mismatch " << impl.m_trait_args << " vs " << e.trait.m_params);
if( best_impl == nullptr || impl.more_specific_than(*best_impl) ) {
@@ -217,19 +224,27 @@ namespace {
is_spec = fit->second.is_specialisable;
)
)
- best_impl_params = mv$( impl_ref.m_data.as_TraitImpl().params );
+ best_impl_params.clear();
+ for(unsigned int i = 0; i < impl_ref_e.params.size(); i ++)
+ {
+ if( impl_ref_e.params[i] )
+ best_impl_params.push_back( impl_ref_e.params[i]->clone() );
+ else if( ! impl_ref_e.params_ph[i].m_data.is_Generic() )
+ best_impl_params.push_back( impl_ref_e.params_ph[i].clone() );
+ else
+ BUG(sp, "Parameter " << i << " unset");
+ }
return !is_spec;
}
return false;
});
+ if( is_dynamic )
+ return EntPtr::make_VTable( {} );
if( !best_impl )
return EntPtr {};
const auto& impl = *best_impl;
- for(const auto* ty_ptr : best_impl_params) {
- ASSERT_BUG(sp, ty_ptr, "Parameter unset");
- impl_pp.m_types.push_back( ty_ptr->clone() );
- }
+ impl_pp.m_types = mv$(best_impl_params);
TU_MATCHA( (trait_vi), (ve),
(Constant, TODO(sp, "Associated constant"); ),
@@ -289,10 +304,22 @@ void Trans_Enumerate_FillFrom_Path(TransList& out, const ::HIR::Crate& crate, co
BUG(sp, "Item not found for " << path_mono);
),
(VTable,
- // TODO: Vtable generation
- //if( auto* ptr = out.add_vtable(mv$(path_mono)) )
- //{
- //}
+ // This is returned either if the item is <T as U>::#vtable or if it's <(Trait) as Trait>::method
+ if( path_mono.m_data.as_UfcsKnown().item == "#vtable" )
+ {
+ // TODO: Vtable generation
+ //if( auto* ptr = out.add_vtable(mv$(path_mono)) )
+ //{
+ //}
+ }
+ else if( path_mono.m_data.as_UfcsKnown().type->m_data.is_TraitObject() )
+ {
+ // Must have been a dynamic dispatch request, just leave as-is
+ }
+ else
+ {
+ BUG(sp, "");
+ }
),
(Function,
// Add this path (monomorphised) to the queue