diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-19 08:27:00 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-19 08:27:00 +0800 |
commit | b589ef3e4437eb6eb5979240694499cec5a44f75 (patch) | |
tree | cda578d434c5d22adc65d3e97870000373c0b972 | |
parent | 551baa8444eb73d9323609ae547bdf7d717417a0 (diff) | |
download | mrust-b589ef3e4437eb6eb5979240694499cec5a44f75.tar.gz |
HIR Expand Closures - Fix bad types
-rw-r--r-- | src/hir_expand/closures.cpp | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 2c846f65..d3f39f19 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -126,7 +126,7 @@ namespace { binding_it = ::std::find(m_captures.begin(), m_captures.end(), node.m_slot); if( binding_it != m_captures.end() ) { m_replacement = NEWNODE(node.m_res_type.clone(), Field, node.span(), - NEWNODE(m_closure_type.clone(), Variable, node.span(), "self", 0), + get_self(node.span()), FMT(binding_it - m_captures.begin()) ); return ; @@ -134,6 +134,31 @@ namespace { BUG(node.span(), "Encountered non-captured and unknown-origin variable - " << node.m_name << " #" << node.m_slot); } + + ::HIR::ExprNodeP get_self(const Span& sp) const + { + ::HIR::ExprNodeP self; + switch( m_closure_type.m_data.as_Closure().node->m_class ) + { + case ::HIR::ExprNode_Closure::Class::Unknown: + // Assume it's NoCapture + case ::HIR::ExprNode_Closure::Class::NoCapture: + case ::HIR::ExprNode_Closure::Class::Shared: + self = NEWNODE(m_closure_type.clone(), Deref, sp, + NEWNODE( ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, m_closure_type.clone()), Variable, sp, "self", 0) + ); + break; + case ::HIR::ExprNode_Closure::Class::Mut: + self = NEWNODE(m_closure_type.clone(), Deref, sp, + NEWNODE( ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Unique, m_closure_type.clone()), Variable, sp, "self", 0) + ); + break; + case ::HIR::ExprNode_Closure::Class::Once: + self = NEWNODE(m_closure_type.clone(), Variable, sp, "self", 0); + break; + } + return self; + } }; /// Visitor to replace closure types with actual type @@ -202,6 +227,7 @@ namespace { struct H { static void fix_fn_params(::HIR::ExprPtr& code, const ::HIR::TypeRef& self_ty, const ::HIR::TypeRef& args_ty) { + // TODO: The self_ty here is wrong, the borrow needs to be included. if( code.m_bindings.size() == 0 ) { // No bindings - Wrapper function // Insert 0 = Self, 1 = Args @@ -256,7 +282,8 @@ namespace { ::HIR::ExprPtr code ) { - fix_fn_params(code, closure_type, args_argent.second); + auto ty_of_self = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Unique, closure_type.clone() ); + fix_fn_params(code, ty_of_self, args_argent.second); return ::HIR::TraitImpl { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( @@ -289,7 +316,8 @@ namespace { ::HIR::ExprPtr code ) { - fix_fn_params(code, closure_type, args_argent.second); + auto ty_of_self = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, closure_type.clone() ); + fix_fn_params(code, ty_of_self, args_argent.second); return ::HIR::TraitImpl { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( |