summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-09-12 00:25:22 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-09-12 00:25:22 +0800
commit419451d2b4e4f5f93c3abeb11235108c7e6bdeb6 (patch)
tree846c7521e5f1595ba418cd9c22408eb47dbc5796 /src
parent95800dfca7309a1f5303317f69860d31d5ce0f39 (diff)
downloadmrust-419451d2b4e4f5f93c3abeb11235108c7e6bdeb6.tar.gz
HIR Resolve - Replace default types, with correct Self replacement
Diffstat (limited to 'src')
-rw-r--r--src/hir_conv/bind.cpp33
-rw-r--r--src/hir_typeck/helpers.cpp3
-rw-r--r--src/hir_typeck/static.cpp10
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];
}