diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-06 16:23:46 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-06 16:23:46 +0800 |
commit | 665728982620dcffc4c3ee9eb4a4b96f3d4c7586 (patch) | |
tree | 4f80563df1e8812177931802058e4f22b1e6c3fb | |
parent | 61f9b4d048d72988855ef2606cc4363128ba8ae9 (diff) | |
download | mrust-665728982620dcffc4c3ee9eb4a4b96f3d4c7586.tar.gz |
HIR Typecheck CS - `self` class determining
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 8c8ff62d..dff4bf23 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1745,8 +1745,9 @@ namespace { this->m_completed = true; } void visit(::HIR::ExprNode_CallMethod& node) override { + const auto& sp = node.span(); + const auto& ty = this->context.get_type(node.m_value->m_res_type); - //const auto ty = this->context.m_resolve.expand_associated_types(node.span(), this->context.get_type(node.m_value->m_res_type).clone()); TRACE_FUNCTION_F("(CallMethod) {" << this->context.m_ivars.fmt_type(ty) << "}." << node.m_method << node.m_params); // Make sure that no mentioned types are inferred until this method is known @@ -1819,26 +1820,64 @@ namespace { // Autoref { - // TODO: Get the unmangled receiver type + // TODO: Get the receiver type without Self having been expanded. + // - Or some other indication of how Self is being taken 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; + enum class Receiver { + Unknown, + Value, + Shared, + Unique, + Owned, + //Box, + } receiver_class = Receiver::Unknown; + if( this->context.m_ivars.types_equal(receiver_type, node.m_value->m_res_type) ) { + receiver_class = Receiver::Value; + } + else TU_IFLET(::HIR::TypeRef::Data, receiver_type.m_data, Borrow, e, + if( this->context.m_ivars.types_equal(*e.inner, node.m_value->m_res_type) ) { + switch(e.type) + { + case ::HIR::BorrowType::Shared: receiver_class = Receiver::Shared; break; + case ::HIR::BorrowType::Unique: receiver_class = Receiver::Unique; break; + case ::HIR::BorrowType::Owned : receiver_class = Receiver::Owned ; break; + } + } + else { + receiver_class = Receiver::Unknown; + } + ) + else { + receiver_class = Receiver::Unknown; + } + + auto& node_ptr = node.m_value; + auto span = node_ptr->span(); + switch(receiver_class) + { + case Receiver::Unknown: + BUG(sp, "Unknown receiver type - " << receiver_type << ", Self = " << node.m_value->m_res_type); + case Receiver::Value: + // by value - nothing needs to be added + break; + case Receiver::Shared: + case Receiver::Unique: + case Receiver::Owned: { + ::HIR::BorrowType bt; + ::HIR::ExprNode_UniOp::Op op; + switch(receiver_class) + { + case Receiver::Shared: op = ::HIR::ExprNode_UniOp::Op::Ref; bt = ::HIR::BorrowType::Shared; break; + case Receiver::Unique: op = ::HIR::ExprNode_UniOp::Op::RefMut; bt = ::HIR::BorrowType::Unique; break; + case Receiver::Owned: TODO(sp, "Construct &move uni-op"); + default: throw ""; + } // - 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*/ - ); + auto ty = ::HIR::TypeRef::new_borrow(bt, node_ptr->m_res_type.clone()); 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 + } break; } } |