summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-07 16:21:26 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-07 16:21:26 +0800
commitf8662cb4f94b078259989769c19522754d1f8323 (patch)
tree9b3f9833e5ccdb12fdb028f4331bed25dce85b20
parent4590285dd0dc83c27dea159232582fef280dd7d6 (diff)
downloadmrust-f8662cb4f94b078259989769c19522754d1f8323.tar.gz
HIR Expand Closures - Fleshing out, almost ready to call from main
-rw-r--r--src/hir_expand/closures.cpp95
-rw-r--r--src/hir_expand/main_bindings.hpp9
2 files changed, 99 insertions, 5 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index 9825f8dd..c5a0a189 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -9,6 +9,7 @@
#include <hir/expr.hpp>
#include <hir_typeck/static.hpp>
#include <algorithm>
+#include "main_bindings.hpp"
namespace {
@@ -68,6 +69,7 @@ namespace {
// 1. Iterate over the nodes and rewrite variable accesses to either renumbered locals, or field accesses
// 2. Construct closure type (saving path/index in the node)
// 3. Create trait impls
+ TODO(node.span(), "Transform closure code into closure type - " << node.m_res_type);
}
void visit(::HIR::ExprNode_Let& node) override
@@ -127,6 +129,88 @@ namespace {
::HIR::ExprVisitorDef::visit(node);
}
}
+ void visit(::HIR::ExprNode_BinOp& node) override
+ {
+ if( !m_closure_stack.empty() )
+ {
+ switch(node.m_op)
+ {
+ case ::HIR::ExprNode_BinOp::Op::CmpEqu:
+ case ::HIR::ExprNode_BinOp::Op::CmpNEqu:
+ case ::HIR::ExprNode_BinOp::Op::CmpLt:
+ case ::HIR::ExprNode_BinOp::Op::CmpLtE:
+ case ::HIR::ExprNode_BinOp::Op::CmpGt:
+ case ::HIR::ExprNode_BinOp::Op::CmpGtE:
+ m_usage.push_back( Usage::Borrow );
+ break;
+ default:
+ m_usage.push_back( Usage::Move );
+ break;
+ }
+
+ node.m_left ->visit(*this);
+ node.m_right->visit(*this);
+
+ m_usage.pop_back();
+ }
+ else
+ {
+ ::HIR::ExprVisitorDef::visit(node);
+ }
+ }
+ void visit(::HIR::ExprNode_Field& node) override
+ {
+ if( !m_closure_stack.empty() )
+ {
+ // If attempting to use a Copy type by value, it can just be a Borrow of the inner type
+ if( 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();
+ }
+ else {
+ node.m_value->visit( *this );
+ }
+ }
+ else
+ {
+ ::HIR::ExprVisitorDef::visit(node);
+ }
+ }
+
+ void visit(::HIR::ExprNode_CallValue& node) override
+ {
+ TODO(node.span(), "Determine how value in CallValue is used");
+ }
+ void visit(::HIR::ExprNode_CallMethod& node) override
+ {
+ if( !m_closure_stack.empty() )
+ {
+ m_usage.push_back(Usage::Move);
+ node.m_value->visit(*this);
+ for(auto& arg : node.m_args)
+ arg->visit(*this);
+ m_usage.pop_back();
+ }
+ else
+ {
+ ::HIR::ExprVisitorDef::visit(node);
+ }
+ }
+ void visit(::HIR::ExprNode_CallPath& node) override
+ {
+ if( !m_closure_stack.empty() )
+ {
+ m_usage.push_back(Usage::Move);
+ for(auto& arg : node.m_args)
+ arg->visit(*this);
+ m_usage.pop_back();
+ }
+ else
+ {
+ ::HIR::ExprVisitorDef::visit(node);
+ }
+ }
private:
bool type_is_copy(const ::HIR::TypeRef& ty) const
{
@@ -287,7 +371,7 @@ namespace {
DEBUG("Array size " << ty);
if( e.size ) {
::std::vector< ::HIR::TypeRef> tmp;
- ExprVisitor_Extract ev({});
+ ExprVisitor_Extract ev(m_resolve, tmp);
ev.visit_root( *e.size );
}
)
@@ -303,8 +387,9 @@ namespace {
if( item.m_code )
{
DEBUG("Function code " << p);
+ ::std::vector< ::HIR::TypeRef> tmp;
//ExprVisitor_Extract ev(item.m_code.binding_types);
- ExprVisitor_Extract ev({});
+ ExprVisitor_Extract ev(m_resolve, tmp);
ev.visit_root( *item.m_code );
}
else
@@ -316,7 +401,7 @@ namespace {
if( item.m_value )
{
::std::vector< ::HIR::TypeRef> tmp;
- ExprVisitor_Extract ev(tmp);
+ ExprVisitor_Extract ev(m_resolve, tmp);
ev.visit_root(*item.m_value);
}
}
@@ -324,7 +409,7 @@ namespace {
if( item.m_value )
{
::std::vector< ::HIR::TypeRef> tmp;
- ExprVisitor_Extract ev({});
+ ExprVisitor_Extract ev(m_resolve, tmp);
ev.visit_root(*item.m_value);
}
}
@@ -339,7 +424,7 @@ namespace {
DEBUG("Enum value " << p << " - " << var.first);
::std::vector< ::HIR::TypeRef> tmp;
- ExprVisitor_Extract ev(tmp);
+ ExprVisitor_Extract ev(m_resolve, tmp);
ev.visit_root(*e);
)
}
diff --git a/src/hir_expand/main_bindings.hpp b/src/hir_expand/main_bindings.hpp
new file mode 100644
index 00000000..2ead572d
--- /dev/null
+++ b/src/hir_expand/main_bindings.hpp
@@ -0,0 +1,9 @@
+/*
+ */
+#pragma once
+
+namespace HIR {
+ class Crate;
+};
+
+extern void HIR_Expand_Closures(::HIR::Crate& crate);