diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-14 22:57:12 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-14 22:57:12 +0800 |
commit | 0387a1cd8c8594dc9e111e9c75af812043f7f367 (patch) | |
tree | 8282625ba581406aea5462c1618dada71c08c918 /src | |
parent | 4dfe5c315498ef816baa3c62e36bc0d72cff50a9 (diff) | |
download | mrust-0387a1cd8c8594dc9e111e9c75af812043f7f367.tar.gz |
HIR Expand - Work on doing Deref desugar
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_expand/annotate_value_usage.cpp | 8 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 74 | ||||
-rw-r--r-- | src/hir_expand/ufcs_everything.cpp | 71 |
3 files changed, 79 insertions, 74 deletions
diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index eec4fd86..0d8bf891 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -65,6 +65,11 @@ namespace { void visit_node_ptr(::HIR::ExprNodeP& node_ptr) override { assert(node_ptr); + + const auto& node_ref = *node_ptr; + const char* node_tyname = typeid(node_ref).name(); + TRACE_FUNCTION_FR(&*node_ptr << " " << node_tyname, node_ptr->m_usage); + node_ptr->m_usage = this->get_usage(); auto expected_size = m_usage.size(); @@ -240,7 +245,7 @@ namespace { this->visit_node_ptr(node.m_value); } else { - node.m_value->visit( *this ); + this->visit_node_ptr(node.m_value); } } @@ -361,6 +366,7 @@ namespace { // ------ void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override { auto _ = this->m_resolve.set_item_generics(item.m_params); + DEBUG("Function " << p); ::HIR::Visitor::visit_function(p, item); } void visit_static(::HIR::ItemPath p, ::HIR::Static& item) override { diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 0a6c2cb6..2ca66da4 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -480,54 +480,6 @@ namespace { ::HIR::ExprVisitorDef::visit(node); } - void visit(::HIR::ExprNode_Assign& node) override - { - // If closure is set, set a flag on the LHS saying it's being mutated, and one on the RHS saying it's being moved. - if( !m_closure_stack.empty() ) - { - node.m_slot->visit(*this); - node.m_value->visit(*this); - } - else - { - ::HIR::ExprVisitorDef::visit(node); - } - } - void visit(::HIR::ExprNode_UniOp& node) override - { - if( !m_closure_stack.empty() ) - { - node.m_value->visit(*this); - } - else - { - ::HIR::ExprVisitorDef::visit(node); - } - } - void visit(::HIR::ExprNode_BinOp& node) override - { - if( !m_closure_stack.empty() ) - { - node.m_left ->visit(*this); - node.m_right->visit(*this); - } - else - { - ::HIR::ExprVisitorDef::visit(node); - } - } - void visit(::HIR::ExprNode_Field& node) override - { - if( !m_closure_stack.empty() ) - { - node.m_value->visit( *this ); - } - else - { - ::HIR::ExprVisitorDef::visit(node); - } - } - void visit(::HIR::ExprNode_CallValue& node) override { if( !m_closure_stack.empty() ) @@ -560,31 +512,7 @@ namespace { ::HIR::ExprVisitorDef::visit(node); } } - void visit(::HIR::ExprNode_CallMethod& node) override - { - if( !m_closure_stack.empty() ) - { - node.m_value->visit(*this); - for(auto& arg : node.m_args) - arg->visit(*this); - } - else - { - ::HIR::ExprVisitorDef::visit(node); - } - } - void visit(::HIR::ExprNode_CallPath& node) override - { - if( !m_closure_stack.empty() ) - { - for(auto& arg : node.m_args) - arg->visit(*this); - } - else - { - ::HIR::ExprVisitorDef::visit(node); - } - } + private: bool type_is_copy(const ::HIR::TypeRef& ty) const { diff --git a/src/hir_expand/ufcs_everything.cpp b/src/hir_expand/ufcs_everything.cpp index 84735f45..8bc40c61 100644 --- a/src/hir_expand/ufcs_everything.cpp +++ b/src/hir_expand/ufcs_everything.cpp @@ -35,7 +35,9 @@ namespace { TRACE_FUNCTION_FR(&*root << " " << node_ty << " : " << root->m_res_type, node_ty); root->visit(*this); if( m_replacement ) { + auto usage = root->m_usage; root.reset( m_replacement.release() ); + root->m_usage = usage; } } @@ -46,7 +48,9 @@ namespace { assert( node ); node->visit(*this); if( m_replacement ) { + auto usage = node->m_usage; node = mv$(m_replacement); + node->m_usage = usage; } } @@ -587,6 +591,73 @@ namespace { // - Dereference the result (which is an &-ptr) m_replacement = NEWNODE( mv$(node.m_res_type), Deref, sp, mv$(m_replacement) ); } + + void visit(::HIR::ExprNode_Deref& node) override + { + const auto& sp = node.span(); + + ::HIR::ExprVisitorDef::visit(node); + + const auto& ty_val = node.m_value->m_res_type; + + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_val.m_data), (e), + ( + BUG(sp, "Deref on unexpected type - " << ty_val); + ), + (Path, + ), + (Pointer, + return ; + ), + (Borrow, + return ; + ) + ) + + const char* langitem = nullptr; + const char* method = nullptr; + ::HIR::BorrowType bt; + switch( node.m_value->m_usage ) + { + case ::HIR::ValueUsage::Unknown: + BUG(sp, "Unknown usage type of deref value"); + break; + case ::HIR::ValueUsage::Borrow: + bt = ::HIR::BorrowType::Shared; + langitem = method = "deref"; + break; + case ::HIR::ValueUsage::Mutate: + bt = ::HIR::BorrowType::Unique; + langitem = method = "deref_mut"; + break; + case ::HIR::ValueUsage::Move: + TODO(sp, "Support moving out of indexed values"); + break; + } + // Needs replacement, continue + assert(langitem); + assert(method); + + // - Construct trait path - Index*<IdxTy> + ::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), {} }; + + ::std::vector< ::HIR::ExprNodeP> args; + args.push_back( NEWNODE( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()), Borrow, sp, bt, mv$(node.m_value) ) ); + + m_replacement = NEWNODE( ::HIR::TypeRef::new_borrow(bt, node.m_res_type.clone()), CallPath, sp, + ::HIR::Path(ty_val.clone(), mv$(trait), method), + mv$(args) + ); + // Populate the cache for later passes + // TODO: The check pass should probably just ignore this and DIY + auto& call_node = dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement); + auto& arg_types = call_node.m_cache.m_arg_types; + arg_types.push_back( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()) ); + arg_types.push_back( m_replacement->m_res_type.clone() ); + + // - Dereference the result (which is an &-ptr) + m_replacement = NEWNODE( mv$(node.m_res_type), Deref, sp, mv$(m_replacement) ); + } }; class OuterVisitor: public ::HIR::Visitor |