summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-25 14:57:07 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-25 14:57:07 +0800
commit3b01d3bba411a4eed45fde195abb2d39b4f6540a (patch)
tree9482357b458d52c62a1fc8ee030f5bccb4498e89 /src
parent89b944a2b71f8937aa1dda81769eb3b852676d28 (diff)
downloadmrust-3b01d3bba411a4eed45fde195abb2d39b4f6540a.tar.gz
HIR Typecheck Expr - Fix incorrect monomorphisation of function pointers
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/common.cpp24
-rw-r--r--src/hir_typeck/expr_cs.cpp25
2 files changed, 40 insertions, 9 deletions
diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp
index e2faeec2..ac23c0a2 100644
--- a/src/hir_typeck/common.cpp
+++ b/src/hir_typeck/common.cpp
@@ -238,20 +238,30 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl)
return rv;
}
+// TODO: Rework this function to support all three classes not just impl-level
+// NOTE: This is _just_ for impl-level parameters
::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl)
{
DEBUG("tpl = " << tpl);
ASSERT_BUG(sp, params.m_types.size() == params_def.m_types.size(), "Parameter count mismatch - exp " << params_def.m_types.size() << ", got " << params.m_types.size());
return monomorphise_type_with(sp, tpl, [&](const auto& gt)->const auto& {
const auto& e = gt.m_data.as_Generic();
- if( e.name == "Self" )
- TODO(sp, "Handle 'Self' when monomorphising");
- //if( e.binding >= params_def.m_types.size() ) {
- //}
- if( e.binding >= params.m_types.size() ) {
- BUG(sp, "Generic param out of input range - " << e.binding << " '"<<e.name<<"' >= " << params.m_types.size());
+ if( e.binding == 0xFFFF ) {
+ TODO(sp, "Handle 'Self' in `monomorphise_type`");
+ }
+ else if( (e.binding >> 8) == 0 ) {
+ auto idx = e.binding & 0xFF;
+ if( idx >= params.m_types.size() ) {
+ BUG(sp, "Generic param out of input range - " << gt << " >= " << params.m_types.size());
+ }
+ return params.m_types[idx];
+ }
+ else if( (e.binding >> 8) == 1 ) {
+ TODO(sp, "Handle fn-level params in `monomorphise_type` - " << gt);
+ }
+ else {
+ BUG(sp, "Unknown param in `monomorphise_type` - " << gt);
}
- return params.m_types[e.binding];
}, false);
}
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 670c52b9..ebb17f52 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1327,15 +1327,36 @@ namespace {
const auto& f = this->context.m_crate.get_function_by_path(sp, e.m_path);
fix_param_count(sp, this->context, e, f.m_params, e.m_params);
+ const auto& params = e.m_params;
+ auto monomorph_cb = [&](const auto& gt)->const auto& {
+ const auto& e = gt.m_data.as_Generic();
+ if( e.binding == 0xFFFF ) {
+ BUG(sp, "Reference to Self in free function - " << gt);
+ }
+ else if( (e.binding >> 8) == 0 ) {
+ BUG(sp, "Reference to impl-level param in free function - " << gt);
+ }
+ else if( (e.binding >> 8) == 1 ) {
+ auto idx = e.binding & 0xFF;
+ if( idx >= params.m_types.size() ) {
+ BUG(sp, "Generic param out of input range - " << gt << " >= " << params.m_types.size());
+ }
+ return params.m_types[idx];
+ }
+ else {
+ BUG(sp, "Unknown param in free function - " << gt);
+ }
+ };
+
::HIR::FunctionType ft {
f.m_unsafe,
f.m_abi,
- box$( monomorphise_type(sp, f.m_params, e.m_params, f.m_return) ),
+ box$( monomorphise_type_with(sp, f.m_return, monomorph_cb) ),
{}
};
for( const auto& arg : f.m_args )
{
- ft.m_arg_types.push_back( monomorphise_type(sp, f.m_params, e.m_params, arg.second) );
+ ft.m_arg_types.push_back( monomorphise_type_with(sp, arg.second, monomorph_cb) );
}
auto ty = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Function(mv$(ft)) );