diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-18 09:52:30 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-18 09:52:30 +0800 |
commit | 6a4bf8a5ac9c37fe98d8bb29ea265c73e595809c (patch) | |
tree | ab940dc15e9d1c2de036cfa8de01bf8c7b95418e /src | |
parent | 2cbced9aea31eb58ec87c4fa58761cdce5da47d3 (diff) | |
download | mrust-6a4bf8a5ac9c37fe98d8bb29ea265c73e595809c.tar.gz |
HIR Typecheck Validate - Fix some small bugs, start on ErasedType support
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_expand/closures.cpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr_check.cpp | 66 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 23 |
3 files changed, 60 insertions, 32 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index aaa6bd85..f5fb2366 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -221,6 +221,9 @@ namespace { DEBUG("Locals"); for(auto& ty : root.m_bindings) visit_type(ty); + + for(auto& ty : root.m_erased_types) + visit_type(ty); } void visit_node_ptr(::HIR::ExprNodeP& node) override diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index e3ec6e51..6153b197 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -13,11 +13,7 @@ namespace { typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > t_args; - // ----------------------------------------------------------------------- - // Enumeration visitor - // - // Iterates the HIR expression tree and extracts type "equations" - // ----------------------------------------------------------------------- + class ExprVisitor_Validate: public ::HIR::ExprVisitor { @@ -34,10 +30,38 @@ namespace { { } - void visit_root(::HIR::ExprNode& node) + void visit_root(::HIR::ExprPtr& node_ptr) { - node.visit(*this); - check_types_equal(node.span(), ret_type, node.m_res_type); + const auto& sp = node_ptr->span(); + node_ptr->visit(*this); + + // TODO: If the return type contains ErasedType, then this check should instead check the structure and bounds. + // > Or just replace ErasedType-s with the known types and then equate + if( visit_ty_with(ret_type, [](const auto& ty) { + if( ty.m_data.is_ErasedType() ) + return true; + return false; + }) ) + { + // Monomorphise erased type + ::HIR::TypeRef new_ret_type = clone_ty_with(sp, ret_type, [&](const auto& tpl, auto& rv) { + if( tpl.m_data.is_ErasedType() ) + { + const auto& e = tpl.m_data.as_ErasedType(); + ASSERT_BUG(sp, e.m_index < node_ptr.m_erased_types.size(), "Erased type index OOB - " << e.m_index << " >= " << node_ptr.m_erased_types.size() << " - " << tpl); + // TODO: Emit checks on bounds + rv = node_ptr.m_erased_types[e.m_index].clone(); + return true; + } + return false; + }); + + check_types_equal(sp, new_ret_type, node_ptr->m_res_type); + } + else + { + check_types_equal(sp, ret_type, node_ptr->m_res_type); + } } void visit(::HIR::ExprNode_Block& node) override @@ -624,19 +648,9 @@ namespace { cache.m_fcn_params = &fcn_ptr->m_params; - // If the impl block has parameters, figure out what types they map to - // - The function params are already mapped (from fix_param_count) + // NOTE: Trusts the existing cache. + ASSERT_BUG(sp, cache.m_ty_impl_params.m_types.size() == impl_ptr->m_params.m_types.size(), ""); auto& impl_params = cache.m_ty_impl_params; - if( impl_ptr->m_params.m_types.size() > 0 ) { - impl_params.m_types.resize( impl_ptr->m_params.m_types.size() ); - impl_ptr->m_type.match_generics(sp, *e.type, [&](const auto&x)->const auto&{return x;}, [&](auto idx, const auto& ty) { - assert( idx < impl_params.m_types.size() ); - impl_params.m_types[idx] = ty.clone(); - return ::HIR::Compare::Equal; - }); - for(const auto& ty : impl_params.m_types) - assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) ); - } // Create monomorphise callback const auto& fcn_params = e.params; @@ -696,7 +710,7 @@ namespace { cache.m_monomorph_cb = mv$(monomorph_cb); - // Bounds (encoded as associated) + // Bounds for(const auto& bound : cache.m_fcn_params->m_bounds) { TU_MATCH(::HIR::GenericBound, (bound), (be), @@ -1009,7 +1023,7 @@ namespace { t_args tmp; auto ty_usize = ::HIR::TypeRef(::HIR::CoreType::Usize); ExprVisitor_Validate ev(m_resolve, tmp, ty_usize); - ev.visit_root( **e.size ); + ev.visit_root( *e.size ); } ) else { @@ -1025,7 +1039,7 @@ namespace { { DEBUG("Function code " << p); ExprVisitor_Validate ev(m_resolve, item.m_args, item.m_return); - ev.visit_root( *item.m_code ); + ev.visit_root( item.m_code ); } else { @@ -1037,7 +1051,7 @@ namespace { { t_args tmp; ExprVisitor_Validate ev(m_resolve, tmp, item.m_type); - ev.visit_root(*item.m_value); + ev.visit_root(item.m_value); } } void visit_constant(::HIR::ItemPath p, ::HIR::Constant& item) override { @@ -1045,7 +1059,7 @@ namespace { { t_args tmp; ExprVisitor_Validate ev(m_resolve, tmp, item.m_type); - ev.visit_root(*item.m_value); + ev.visit_root(item.m_value); } } void visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) override { @@ -1060,7 +1074,7 @@ namespace { t_args tmp; ExprVisitor_Validate ev(m_resolve, tmp, enum_type); - ev.visit_root(*e.expr); + ev.visit_root(e.expr); ) } } diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index f2d2dabe..334ecbe2 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2771,6 +2771,9 @@ namespace { for( auto& ty : node_ptr.m_bindings ) this->check_type_resolved_top(node.span(), ty); + + for( auto& ty : node_ptr.m_erased_types ) + this->check_type_resolved_top(node.span(), ty); } void visit_node_ptr(::HIR::ExprNodeP& node_ptr) override { auto& node = *node_ptr; @@ -2832,15 +2835,23 @@ namespace { ::HIR::ExprVisitorDef::visit(node); } + void visit_callcache(const Span&sp, ::HIR::ExprCallCache& cache) + { + for(auto& ty : cache.m_arg_types) + this->check_type_resolved_top(sp, ty); + + for(auto& ty : cache.m_ty_impl_params.m_types) + this->check_type_resolved_top(sp, ty); + } void visit(::HIR::ExprNode_CallPath& node) override { - for(auto& ty : node.m_cache.m_arg_types) - this->check_type_resolved_top(node.span(), ty); + this->visit_callcache(node.span(), node.m_cache); + this->check_type_resolved_path(node.span(), node.m_path); ::HIR::ExprVisitorDef::visit(node); } void visit(::HIR::ExprNode_CallMethod& node) override { - for(auto& ty : node.m_cache.m_arg_types) - this->check_type_resolved_top(node.span(), ty); + this->visit_callcache(node.span(), node.m_cache); + this->check_type_resolved_path(node.span(), node.m_method_path); ::HIR::ExprVisitorDef::visit(node); } @@ -5261,8 +5272,8 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: if( tpl.m_data.is_ErasedType() ) { const auto& e = tpl.m_data.as_ErasedType(); - // TODO: Save this ivar somewhere for users of this function. rv = context.m_ivars.new_ivar_tr(); + expr.m_erased_types.push_back( rv.clone() ); for(const auto& trait : e.m_traits) { if( trait.m_type_bounds.size() == 0 ) @@ -5431,7 +5442,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: } // - Recreate the pointer - expr = ::HIR::ExprPtr( mv$(root_ptr) ); + expr.reset( root_ptr.release() ); // > Steal the binding types expr.m_bindings.reserve( context.m_bindings.size() ); for(auto& binding : context.m_bindings) { |