diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-03 13:45:47 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-03 13:45:47 +0800 |
commit | 16e7559bcca93b885bc0d2480a388960104bf78e (patch) | |
tree | 76f5d07d9a86c7c4932bcc7cce71d0c8c1c4d3ca /src | |
parent | c621ce63d46c6902d26ffe246295da9303143a39 (diff) | |
download | mrust-16e7559bcca93b885bc0d2480a388960104bf78e.tar.gz |
Trans Enumerate - Handle places where monomorph lead to dynamic dispatch
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/static.cpp | 55 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 51 |
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 |