summaryrefslogtreecommitdiff
path: root/src/hir_conv/bind.cpp
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/hir_conv/bind.cpp
parent95800dfca7309a1f5303317f69860d31d5ce0f39 (diff)
downloadmrust-419451d2b4e4f5f93c3abeb11235108c7e6bdeb6.tar.gz
HIR Resolve - Replace default types, with correct Self replacement
Diffstat (limited to 'src/hir_conv/bind.cpp')
-rw-r--r--src/hir_conv/bind.cpp33
1 files changed, 29 insertions, 4 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);