summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-06 09:41:39 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-06 09:41:39 +0800
commit88039f7100b9ce9b831a0cc4d09c5b479c41c58a (patch)
tree0aef55c1931f24f5e76a11683032cbad044eeca3
parentecea2ed5237e57002db68a66b1a88c91788e883b (diff)
downloadmrust-88039f7100b9ce9b831a0cc4d09c5b479c41c58a.tar.gz
HIR Typecheck - Add deref/ref in method calls
-rw-r--r--src/hir_typeck/expr_cs.cpp45
-rw-r--r--src/hir_typeck/helpers.cpp3
2 files changed, 46 insertions, 2 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index dc790c2d..af50c6d9 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1795,7 +1795,50 @@ namespace {
}
this->context.equate_types(node.span(), node.m_res_type, node.m_cache.m_arg_types.back());
- // TODO: Apply derefs!
+ // Add derefs
+ if( deref_count > 0 )
+ {
+ DEBUG("- Inserting " << deref_count << " dereferences");
+ // Get dereferencing!
+ auto& node_ptr = node.m_value;
+ ::HIR::TypeRef tmp_ty;
+ const ::HIR::TypeRef* cur_ty = &node_ptr->m_res_type;
+ while( deref_count-- )
+ {
+ auto span = node_ptr->span();
+ node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Deref( mv$(span), mv$(node_ptr) ));
+ cur_ty = this->context.m_resolve.autoderef(span, *cur_ty, tmp_ty);
+ assert(cur_ty);
+ auto ty = cur_ty->clone();
+ DEBUG("- Deref " << &*node_ptr << " -> " << ty);
+ node_ptr->m_res_type = mv$(ty);
+ }
+ }
+
+ // Autoref
+ {
+ // TODO: Get the unmangled receiver type
+ const auto& receiver_type = node.m_cache.m_arg_types.front();
+ // This only happens when the method is being called on a value
+ // TODO: How to tell the receiver type correctly once Self is expanded? (not a problem for trait methods... but this is monomorphised)
+ TU_IFLET(::HIR::TypeRef::Data, (receiver_type.m_data), Borrow, (e),
+ auto& node_ptr = node.m_value;
+ // - Add correct borrow operation
+ auto span = node_ptr->span();
+ auto ty = ::HIR::TypeRef::new_borrow(e.type, node_ptr->m_res_type.clone());
+ auto op = (
+ e.type == ::HIR::BorrowType::Shared ? ::HIR::ExprNode_UniOp::Op::Ref :
+ /*e.type == ::HIR::BorrowType::Unique ? */::HIR::ExprNode_UniOp::Op::RefMut/* :
+ 0*/
+ );
+ node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_UniOp( mv$(span), op, mv$(node_ptr) ));
+ DEBUG("- Ref " << &*node_ptr << " -> " << ty);
+ node_ptr->m_res_type = mv$(ty);
+ )
+ else {
+ // Nothing needs adding
+ }
+ }
node.m_method_path = mv$(fcn_path);
this->m_completed = true;
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index c4c112b4..ad12b2cb 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -2073,8 +2073,9 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa
// -------------------------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------------------------
-const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::TypeRef& ty, ::HIR::TypeRef& tmp_type) const
+const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::TypeRef& ty_in, ::HIR::TypeRef& tmp_type) const
{
+ const auto& ty = this->m_ivars.get_type(ty_in);
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Borrow, e,
DEBUG("Deref " << ty << " into " << *e.inner);
return &*e.inner;