diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-22 22:31:40 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-22 22:31:40 +0800 |
commit | d2041e74702de2d1749801dc3ab5ff3715dfeb75 (patch) | |
tree | 0b382ad8351e9f1c64c92896a298f81cfd9abf0e /src | |
parent | f459cf31501bba8d61e34a2850023dccf57e2466 (diff) | |
download | mrust-d2041e74702de2d1749801dc3ab5ff3715dfeb75.tar.gz |
HIR Typecheck Expr - Construct a fake TraitObject for Unsize magic
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/helpers.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 4ae49d22..a02da70f 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -1079,27 +1079,44 @@ bool TraitResolution::find_trait_impls(const Span& sp, TU_IFLET( ::HIR::TypeRef::Data, dst_ty.m_data, TraitObject, e, // Magic impl if T: ThisTrait bool good; + + ::HIR::TypeRef::Data::Data_TraitObject tmp_e; + tmp_e.m_trait.m_path = e.m_trait.m_path.m_path; + ::HIR::Compare total_cmp = ::HIR::Compare::Equal; - auto cb = [&](const auto&, auto cmp){ - if( cmp == ::HIR::Compare::Unequal ) - return false; - total_cmp &= cmp; - return true; - }; if( e.m_trait.m_path.m_path == ::HIR::SimplePath() ) { ASSERT_BUG(sp, e.m_markers.size() > 0, "TraitObject with no traits - " << dst_ty); good = true; } else { - good = find_trait_impls(sp, e.m_trait.m_path.m_path, e.m_trait.m_path.m_params, ty, cb); + good = find_trait_impls(sp, e.m_trait.m_path.m_path, e.m_trait.m_path.m_params, ty, + [&](const auto impl, auto cmp){ + if( cmp == ::HIR::Compare::Unequal ) + return false; + total_cmp &= cmp; + tmp_e.m_trait.m_path.m_params = impl.get_trait_params(); + for(const auto& aty : e.m_trait.m_type_bounds) + tmp_e.m_trait.m_type_bounds[aty.first] = impl.get_type(aty.first.c_str()); + return true; + }); } + auto cb = [&](const auto impl, auto cmp){ + if( cmp == ::HIR::Compare::Unequal ) + return false; + total_cmp &= cmp; + tmp_e.m_markers.back().m_params = impl.get_trait_params(); + return true; + }; for(const auto& marker : e.m_markers) { if(!good) break; + tmp_e.m_markers.push_back( marker.m_path ); good &= find_trait_impls(sp, marker.m_path, marker.m_params, ty, cb); } if( good ) { - return callback( ImplRef(type.clone(), params.clone(), {}), total_cmp ); + // TODO: params.clone() isn't quite right. + ::HIR::PathParams real_params { ::HIR::TypeRef( ::HIR::TypeRef::Data(mv$(tmp_e)) ) }; + return callback( ImplRef(type.clone(), mv$(real_params), {}), total_cmp ); } else { return false; |