diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-06 09:41:39 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-06 09:41:39 +0800 |
commit | 88039f7100b9ce9b831a0cc4d09c5b479c41c58a (patch) | |
tree | 0aef55c1931f24f5e76a11683032cbad044eeca3 | |
parent | ecea2ed5237e57002db68a66b1a88c91788e883b (diff) | |
download | mrust-88039f7100b9ce9b831a0cc4d09c5b479c41c58a.tar.gz |
HIR Typecheck - Add deref/ref in method calls
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 45 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 3 |
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; |