diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-09-12 00:25:22 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-09-12 00:25:22 +0800 |
commit | 419451d2b4e4f5f93c3abeb11235108c7e6bdeb6 (patch) | |
tree | 846c7521e5f1595ba418cd9c22408eb47dbc5796 /src | |
parent | 95800dfca7309a1f5303317f69860d31d5ce0f39 (diff) | |
download | mrust-419451d2b4e4f5f93c3abeb11235108c7e6bdeb6.tar.gz |
HIR Resolve - Replace default types, with correct Self replacement
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_conv/bind.cpp | 33 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 10 |
3 files changed, 39 insertions, 7 deletions
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 553d3b27..2deaac9d 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -289,13 +289,14 @@ namespace { ) ) } - static void fix_param_count(const Span& sp, const ::HIR::GenericPath& path, const ::HIR::GenericParams& param_defs, ::HIR::PathParams& params) { + static void fix_param_count(const Span& sp, const ::HIR::GenericPath& path, const ::HIR::GenericParams& param_defs, ::HIR::PathParams& params, bool fill_infer=true, const ::HIR::TypeRef* self_ty=nullptr) + { if( params.m_types.size() == param_defs.m_types.size() ) { // Nothing to do, all good return ; } - if( params.m_types.size() == 0 ) { + if( params.m_types.size() == 0 && fill_infer ) { for(const auto& typ : param_defs.m_types) { (void)typ; params.m_types.push_back( ::HIR::TypeRef() ); @@ -311,12 +312,36 @@ namespace { ERROR(sp, E0000, "Omitted type parameter with no default in " << path); } else { - // TODO: What if this contains a generic param? (is that valid? Self maybe, what about others?) - params.m_types.push_back( typ.m_default.clone() ); + // Clone, replacing `self` if a replacement was provided. + auto ty = clone_ty_with(sp, typ.m_default, [&](const auto& ty, auto& out){ + if(const auto* te = ty.m_data.opt_Generic() ) + { + if( te->binding != GENERIC_Self || !self_ty ) + TODO(sp, "Monomorphise in fix_param_count - encountered " << ty << " in " << typ.m_default); + out = self_ty->clone(); + return true; + } + return false; + }); + params.m_types.push_back( mv$(ty) ); } } } } + void visit_params(::HIR::GenericParams& params) + { + static Span sp; + for(auto& bound : params.m_bounds) + { + if(auto* be = bound.opt_TraitBound()) + { + const auto& trait = m_crate.get_trait_by_path(sp, be->trait.m_path.m_path); + fix_param_count(sp, be->trait.m_path, trait.m_params, be->trait.m_path.m_params, /*fill_infer=*/false, &be->type); + } + } + + ::HIR::Visitor::visit_params(params); + } void visit_type(::HIR::TypeRef& ty) override { //TRACE_FUNCTION_F(ty); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 6665bcd1..eb8fef0a 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -2786,7 +2786,8 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); ASSERT_BUG(sp, ge.binding >> 8 != 2, ""); - assert( ge.binding < impl_params.size() ); + ASSERT_BUG(sp, ge.binding != GENERIC_Self, "Unexpected Self"); + ASSERT_BUG(sp, ge.binding < impl_params.size(), "OOB param in impl - " << gt ); if( !impl_params[ge.binding] ) { //BUG(sp, "Param " << ge.binding << " for `impl" << impl.m_params.fmt_args() << " " << trait << impl.m_trait_args << " for " << impl.m_type << "` wasn't constrained"); return placeholders[ge.binding]; diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 83d287b9..53bca030 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -582,8 +582,14 @@ bool StaticTraitResolve::find_impl__check_crate_raw( // Callback that returns monomorpisation results auto cb_monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - ASSERT_BUG(sp, ge.binding >> 8 != 2, ""); - assert( ge.binding < impl_params.size() ); + if( ge.binding == GENERIC_Self ) { + // TODO: `impl_type` or `des_type` + DEBUG("[find_impl__check_crate_raw] Self - " << impl_type << " or " << des_type); + //TODO(sp, "[find_impl__check_crate_raw] Self - " << impl_type << " or " << des_type); + return impl_type; + } + ASSERT_BUG(sp, ge.binding >> 8 != 2, "[find_impl__check_crate_raw] Placeholder param seen - " << gt); + ASSERT_BUG(sp, ge.binding < impl_params.size(), "[find_impl__check_crate_raw] Binding out of range - " << gt); if( !impl_params[ge.binding] ) { return placeholders[ge.binding]; } |