summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-18 09:52:30 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-18 09:52:30 +0800
commit6a4bf8a5ac9c37fe98d8bb29ea265c73e595809c (patch)
treeab940dc15e9d1c2de036cfa8de01bf8c7b95418e /src
parent2cbced9aea31eb58ec87c4fa58761cdce5da47d3 (diff)
downloadmrust-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.cpp3
-rw-r--r--src/hir_typeck/expr_check.cpp66
-rw-r--r--src/hir_typeck/expr_cs.cpp23
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) {