summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-14 22:57:12 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-14 22:57:12 +0800
commit0387a1cd8c8594dc9e111e9c75af812043f7f367 (patch)
tree8282625ba581406aea5462c1618dada71c08c918 /src
parent4dfe5c315498ef816baa3c62e36bc0d72cff50a9 (diff)
downloadmrust-0387a1cd8c8594dc9e111e9c75af812043f7f367.tar.gz
HIR Expand - Work on doing Deref desugar
Diffstat (limited to 'src')
-rw-r--r--src/hir_expand/annotate_value_usage.cpp8
-rw-r--r--src/hir_expand/closures.cpp74
-rw-r--r--src/hir_expand/ufcs_everything.cpp71
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