summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-14 18:10:18 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-14 18:10:18 +0800
commitbf6921f2d4da611ce75e560136a0019bbc9c182a (patch)
tree27d3337fae3d8e5a88b40355f526088bf3639010
parent399445e13bd9c99993f758734103c8c7dbf1036e (diff)
downloadmrust-bf6921f2d4da611ce75e560136a0019bbc9c182a.tar.gz
HIR Expand Calls - Add Index desugar
-rw-r--r--src/hir/expr.hpp10
-rw-r--r--src/hir_expand/ufcs_everything.cpp51
2 files changed, 60 insertions, 1 deletions
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index 137377d7..f69429f6 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -22,6 +22,16 @@ enum class ValueUsage {
// Value is moved
Move,
};
+static inline ::std::ostream& operator<<(::std::ostream& os, const ValueUsage& x) {
+ switch(x)
+ {
+ case ValueUsage::Unknown: os << "Unknown"; break;
+ case ValueUsage::Borrow: os << "Borrow"; break;
+ case ValueUsage::Mutate: os << "Mutate"; break;
+ case ValueUsage::Move: os << "Move"; break;
+ }
+ return os;
+}
class GenericParams;
diff --git a/src/hir_expand/ufcs_everything.cpp b/src/hir_expand/ufcs_everything.cpp
index 670d493d..3785d86c 100644
--- a/src/hir_expand/ufcs_everything.cpp
+++ b/src/hir_expand/ufcs_everything.cpp
@@ -549,7 +549,56 @@ namespace {
)
// TODO: Which trait should be used?
- TODO(sp, "Determine which trait should be used for index overload");
+ const char* langitem = nullptr;
+ const char* method = nullptr;
+ ::HIR::BorrowType bt;
+ ::HIR::ExprNode_UniOp::Op op;
+ switch( node.m_value->m_usage )
+ {
+ case ::HIR::ValueUsage::Unknown:
+ BUG(sp, "Usage of value in index op is unknown");
+ break;
+ case ::HIR::ValueUsage::Borrow:
+ bt = ::HIR::BorrowType::Shared;
+ op = ::HIR::ExprNode_UniOp::Op::Ref;
+ langitem = method = "index";
+ break;
+ case ::HIR::ValueUsage::Mutate:
+ bt = ::HIR::BorrowType::Unique;
+ op = ::HIR::ExprNode_UniOp::Op::RefMut;
+ langitem = method = "index_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::PathParams pp;
+ pp.m_types.push_back( ty_idx.clone() );
+ ::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), mv$(pp) };
+
+ ::std::vector< ::HIR::ExprNodeP> args;
+ args.push_back( NEWNODE( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()), UniOp, sp, op, mv$(node.m_value) ) );
+ args.push_back( mv$(node.m_index) );
+
+ 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( ty_idx.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: