diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-24 11:44:08 +1100 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-24 11:44:08 +1100 |
commit | 07e150e9d7d638977ba3a1561d2687950a2a4668 (patch) | |
tree | 153faf4ceff6b1397fb0c76e40ef51dd311578c2 /src/hir_expand/closures.cpp | |
parent | 4d8c5a1a0ea1fea86e0e8b4be30ce0c77411f9c2 (diff) | |
download | mrust-07e150e9d7d638977ba3a1561d2687950a2a4668.tar.gz |
HIR Expand Closures - Handle closures called from other closures
Diffstat (limited to 'src/hir_expand/closures.cpp')
-rw-r--r-- | src/hir_expand/closures.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 0923e494..71e6a8c2 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -795,31 +795,49 @@ namespace { void visit(::HIR::ExprNode_CallValue& node) override { + const auto& fcn_ty = node.m_value->m_res_type; + DEBUG("_CallValue - " << fcn_ty); if( !m_closure_stack.empty() ) { TRACE_FUNCTION_F("_CallValue"); if( node.m_trait_used == ::HIR::ExprNode_CallValue::TraitUsed::Unknown ) { - if( node.m_res_type.m_data.is_Closure() ) + if( fcn_ty.m_data.is_Closure() ) { - TODO(node.span(), "Determine how value in CallValue is used on a closure"); + const auto& cn = *fcn_ty.m_data.as_Closure().node; + // Use the closure's class to determine if & or &mut should be taken (and which function to use) + ::HIR::ValueUsage vu = ::HIR::ValueUsage::Unknown; + switch(cn.m_class) + { + case ::HIR::ExprNode_Closure::Class::Unknown: + case ::HIR::ExprNode_Closure::Class::NoCapture: + case ::HIR::ExprNode_Closure::Class::Shared: + vu = ::HIR::ValueUsage::Borrow; + break; + case ::HIR::ExprNode_Closure::Class::Mut: + vu = ::HIR::ValueUsage::Mutate; + break; + case ::HIR::ExprNode_Closure::Class::Once: + vu = ::HIR::ValueUsage::Move; + break; + } + node.m_value->m_usage = vu; } else { + // Must be a function pointer, leave it } } else { // If the trait is known, then the &/&mut has been added } - - node.m_value->visit(*this); - for(auto& arg : node.m_args) - arg->visit(*this); + ::HIR::ExprVisitorDef::visit(node); } - else if( node.m_res_type.m_data.is_Closure() ) + else if( fcn_ty.m_data.is_Closure() ) { - TODO(node.span(), "Determine how value in CallValue is used on a closure"); + //TODO(node.span(), "Determine how value in CallValue is used on a closure"); + ::HIR::ExprVisitorDef::visit(node); } else { |