diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-25 14:57:07 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-25 14:57:07 +0800 |
commit | 3b01d3bba411a4eed45fde195abb2d39b4f6540a (patch) | |
tree | 9482357b458d52c62a1fc8ee030f5bccb4498e89 /src | |
parent | 89b944a2b71f8937aa1dda81769eb3b852676d28 (diff) | |
download | mrust-3b01d3bba411a4eed45fde195abb2d39b4f6540a.tar.gz |
HIR Typecheck Expr - Fix incorrect monomorphisation of function pointers
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/common.cpp | 24 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 25 |
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)) ); |