summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-18 22:03:32 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-18 22:03:32 +0800
commit273bdd41d46ce0558877af7fa10bc665b92721d5 (patch)
tree77dcb52f1b3e1a4a2537e9ec13a5940ceb6dc427 /src
parent9ceef3de36f310e45913a5fcc60696609ea0a31f (diff)
downloadmrust-273bdd41d46ce0558877af7fa10bc665b92721d5.tar.gz
HIR - Move closures
Diffstat (limited to 'src')
-rw-r--r--src/ast/expr.cpp2
-rw-r--r--src/ast/expr.hpp6
-rw-r--r--src/expand/derive.cpp7
-rw-r--r--src/hir/expr.hpp7
-rw-r--r--src/hir/from_ast_expr.cpp3
-rw-r--r--src/hir_expand/closures.cpp12
-rw-r--r--src/parse/expr.cpp2
7 files changed, 26 insertions, 13 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp
index b39a2c3a..d3fa1989 100644
--- a/src/ast/expr.cpp
+++ b/src/ast/expr.cpp
@@ -251,7 +251,7 @@ NODE(ExprNode_Closure, {
for(const auto& a : m_args) {
args.push_back( ::std::make_pair(a.first.clone(), a.second.clone()) );
}
- return NEWNODE(ExprNode_Closure, mv$(args), m_return.clone(), m_code->clone());
+ return NEWNODE(ExprNode_Closure, mv$(args), m_return.clone(), m_code->clone(), m_is_move);
});
NODE(ExprNode_StructLiteral, {
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp
index e2c318b1..e955a4a4 100644
--- a/src/ast/expr.hpp
+++ b/src/ast/expr.hpp
@@ -370,11 +370,13 @@ struct ExprNode_Closure:
args_t m_args;
TypeRef m_return;
unique_ptr<ExprNode> m_code;
+ bool m_is_move;
- ExprNode_Closure(args_t args, TypeRef rv, unique_ptr<ExprNode> code):
+ ExprNode_Closure(args_t args, TypeRef rv, unique_ptr<ExprNode> code, bool is_move):
m_args( ::std::move(args) ),
m_return( ::std::move(rv) ),
- m_code( ::std::move(code) )
+ m_code( ::std::move(code) ),
+ m_is_move( is_move )
{}
NODE_METHODS();
diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp
index 6d1e7e83..f6021a7d 100644
--- a/src/expand/derive.cpp
+++ b/src/expand/derive.cpp
@@ -1653,7 +1653,7 @@ class Deriver_RustcEncodable:
AST::ExprNodeP enc_closure(Span sp, AST::ExprNodeP code) const {
return NEWNODE(Closure,
vec$( ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "s"), ::TypeRef(sp) ) ), ::TypeRef(sp),
- mv$(code)
+ mv$(code), false
);
}
AST::ExprNodeP get_val_ok(const ::std::string& core_name) const {
@@ -1877,7 +1877,7 @@ class Deriver_RustcDecodable:
AST::ExprNodeP dec_closure(Span sp, AST::ExprNodeP code) const {
return NEWNODE(Closure,
vec$( ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "d"), ::TypeRef(sp) ) ), ::TypeRef(sp),
- mv$(code)
+ mv$(code), false
);
}
AST::ExprNodeP get_val_err_str(const ::std::string& core_name, ::std::string err_str) const {
@@ -2036,7 +2036,8 @@ public:
::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "idx"), ::TypeRef(sp) )
),
::TypeRef(sp),
- mv$(node_match)
+ mv$(node_match),
+ false
);
const ::std::string& enum_name = type.m_data.as_Path().path.nodes().back().name();
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index b963834f..5bb7f248 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -756,6 +756,7 @@ struct ExprNode_Closure:
args_t m_args;
::HIR::TypeRef m_return;
::HIR::ExprNodeP m_code;
+ bool m_is_move = false;
enum class Class {
Unknown,
@@ -764,18 +765,18 @@ struct ExprNode_Closure:
Mut,
Once,
} m_class = Class::Unknown;
- bool m_is_move = false;
// - Path to the generated closure type
::HIR::GenericPath m_obj_path_base;
::HIR::GenericPath m_obj_path;
::std::vector< ::HIR::ExprNodeP> m_captures;
- ExprNode_Closure(Span sp, args_t args, ::HIR::TypeRef rv, ::HIR::ExprNodeP code):
+ ExprNode_Closure(Span sp, args_t args, ::HIR::TypeRef rv, ::HIR::ExprNodeP code, bool is_move):
ExprNode(mv$(sp)),
m_args( ::std::move(args) ),
m_return( ::std::move(rv) ),
- m_code( ::std::move(code) )
+ m_code( ::std::move(code) ),
+ m_is_move(is_move)
{}
NODE_METHODS();
diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp
index 4c10e91a..273e2b04 100644
--- a/src/hir/from_ast_expr.cpp
+++ b/src/hir/from_ast_expr.cpp
@@ -533,7 +533,8 @@ struct LowerHIR_ExprNode_Visitor:
m_rv.reset( new ::HIR::ExprNode_Closure( v.span(),
mv$(args),
LowerHIR_Type(v.m_return),
- LowerHIR_ExprNode_Inner(*v.m_code)
+ LowerHIR_ExprNode_Inner(*v.m_code),
+ v.m_is_move
) );
}
virtual void visit(::AST::ExprNode_StructLiteral& v) override {
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index 2f593a1d..35071825 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -564,9 +564,17 @@ namespace {
}
+ // - If this closure is a move closure, mutate `captured_vars` such that all captures are tagged with ValueUsage::Move
+ if( node.m_is_move )
+ {
+ for(auto& cap : ent.captured_vars)
+ {
+ cap.second = ::HIR::ValueUsage::Move;
+ }
+ }
+
DEBUG("--- Mutate inner code");
// 2. Iterate over the nodes and rewrite variable accesses to either renumbered locals, or field accesses
- // - TODO: If this closure is a move closure, mutate `captured_vars` such that all captures are tagged with ValueUsage::Move
ExprVisitor_Mutate ev { node.m_res_type, ent.local_vars, ent.captured_vars, monomorph_cb };
ev.visit_node_ptr( node.m_code );
// NOTE: `ev` is used down in `Args` to convert the argument destructuring pattern
@@ -589,7 +597,7 @@ namespace {
for(const auto binding : ent.captured_vars)
{
const auto binding_idx = binding.first;
- const auto binding_type = binding.second;
+ auto binding_type = binding.second;
const auto& cap_ty = m_variable_types.at(binding_idx);
auto ty_mono = monomorphise_type_with(sp, cap_ty, monomorph_cb);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index d6bed032..c71d2b4a 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -1037,7 +1037,7 @@ ExprNodeP Parse_ExprVal_Closure(TokenStream& lex, bool is_move)
auto code = Parse_Expr0(lex);
- return NEWNODE( AST::ExprNode_Closure, ::std::move(args), ::std::move(rt), ::std::move(code) );
+ return NEWNODE( AST::ExprNode_Closure, ::std::move(args), ::std::move(rt), ::std::move(code), is_move );
}
ExprNodeP Parse_ExprVal(TokenStream& lex)