summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-08 10:28:13 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-08 10:28:13 +0800
commit65d1544a868a49024445220d6cc7057a55c0515d (patch)
treed749f30468c65b936e4a3d704c5b042f7f20ed79
parent526326f5c08a09df02bf5c7234220ce008cd956a (diff)
downloadmrust-65d1544a868a49024445220d6cc7057a55c0515d.tar.gz
HIR Expand Closures - Completing now
-rw-r--r--src/hir_expand/closures.cpp33
-rw-r--r--src/hir_typeck/expr_cs.cpp6
2 files changed, 26 insertions, 13 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index f0d10015..e5374327 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -50,11 +50,19 @@ namespace {
{
}
void visit_node_ptr(::HIR::ExprNodeP& node) override {
+ const char* node_ty = typeid(*node).name();
+ TRACE_FUNCTION_FR(&*node << " " << node_ty << " : " << node->m_res_type, node_ty);
+ assert( node );
node->visit(*this);
if( m_replacement ) {
node = mv$(m_replacement);
}
}
+ void visit(::HIR::ExprNode_Closure& node) override
+ {
+ // Do nothing, inner closures should just be value references now
+ assert( ! node.m_code );
+ }
void visit(::HIR::ExprNode_Variable& node) override
{
// 1. Is it a closure-local?
@@ -67,14 +75,14 @@ namespace {
// 2. Is it a capture?
binding_it = ::std::find(m_captures.begin(), m_captures.end(), node.m_slot);
if( binding_it != m_captures.end() ) {
- m_replacement = ::HIR::ExprNodeP( new ::HIR::ExprNode_Field(node.span(),
- ::HIR::ExprNodeP( new ::HIR::ExprNode_Variable(node.span(), "self", 0) ),
+ m_replacement = NEWNODE(Field, node.span(),
+ NEWNODE(Variable, node.span(), "self", 0),
FMT(binding_it - m_captures.begin())
- ));
+ );
return ;
}
- BUG(node.span(), "");
+ BUG(node.span(), "Encountered non-captured and unknown-origin variable - " << node.m_name << " #" << node.m_slot);
}
};
@@ -156,7 +164,7 @@ namespace {
// - Types of captured variables
::std::vector< ::HIR::VisEnt< ::HIR::TypeRef> > capture_types;
for(const auto binding_idx : node.m_var_captures) {
- capture_types.push_back( ::HIR::VisEnt< ::HIR::TypeRef> { false, mv$(m_variable_types.at(binding_idx)) } );
+ capture_types.push_back( ::HIR::VisEnt< ::HIR::TypeRef> { false, m_variable_types.at(binding_idx).clone() } );
}
m_out_types.push_back( ::std::make_pair(
FMT("closure_" << &node),
@@ -445,8 +453,7 @@ namespace {
if( !m_closure_stack.empty() )
{
// If attempting to use a Copy type by value, it can just be a Borrow of the inner type
- assert(m_usage.size() > 0);
- if( m_usage.back() == Usage::Move && type_is_copy(node.m_res_type) ) {
+ if( (m_usage.size() == 0 || m_usage.back() == Usage::Move) && type_is_copy(node.m_res_type) ) {
m_usage.push_back(Usage::Borrow);
node.m_value->visit( *this );
m_usage.pop_back();
@@ -619,14 +626,15 @@ namespace {
}
void mark_used_variable(unsigned int slot)
{
- for(const auto& closure_rec : m_closure_stack)
- {
- const auto& closure_defs = closure_rec.local_vars;
+ //for(const auto& closure_rec : m_closure_stack)
+ //{
+ // const auto& closure_defs = closure_rec.local_vars;
+ const auto& closure_defs = m_closure_stack.back().local_vars;
if( ::std::binary_search(closure_defs.begin(), closure_defs.end(), slot) ) {
// Ignore, this is local to the current closure
return ;
}
- }
+ //}
assert(m_closure_stack.size() > 0 );
auto& closure_rec = m_closure_stack.back();
@@ -636,9 +644,10 @@ namespace {
if( it == closure.m_var_captures.end() || *it != slot ) {
closure.m_var_captures.insert( it, slot );
}
+ DEBUG("Captured " << slot << " - " << m_variable_types.at(slot));
// Use the m_usage variable
- switch( m_usage.back() )
+ switch( m_usage.size() > 0 ? m_usage.back() : Usage::Move )
{
case Usage::Borrow:
closure.m_class = ::std::max(closure.m_class, ::HIR::ExprNode_Closure::Class::Shared);
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 978333d7..dbc948b5 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -3963,9 +3963,13 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:
ExprVisitor_Apply visitor { context };
visitor.visit_node_ptr( root_ptr );
}
+
+ // - Recreate the pointer
expr = ::HIR::ExprPtr( mv$(root_ptr) );
+ // > Steal the binding types
expr.m_bindings.reserve( context.m_bindings.size() );
- for(auto& binding : context.m_bindings)
+ for(auto& binding : context.m_bindings) {
expr.m_bindings.push_back( mv$(binding.ty) );
+ }
}