diff options
-rw-r--r-- | src/ast/expr.cpp | 2 | ||||
-rw-r--r-- | src/ast/expr.hpp | 6 | ||||
-rw-r--r-- | src/expand/derive.cpp | 7 | ||||
-rw-r--r-- | src/hir/expr.hpp | 7 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 3 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 12 | ||||
-rw-r--r-- | src/parse/expr.cpp | 2 |
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)
|