diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-14 18:28:22 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-14 18:28:22 +0800 |
commit | 6f390a1f245d467ef8f2aa7c9e0ad7b300a4e681 (patch) | |
tree | fb4ac806ef3d20cd04e4e48b2272dab4cc3256bf /src | |
parent | bf6921f2d4da611ce75e560136a0019bbc9c182a (diff) | |
download | mrust-6f390a1f245d467ef8f2aa7c9e0ad7b300a4e681.tar.gz |
HIR Typecheck CS - Fix incorrect types in autogenerated borrow
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 97e69ccd..b2cc1dd2 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2985,6 +2985,7 @@ namespace { void add_coerce_borrow(Context& context, ::HIR::ExprNodeP& node_ptr, const ::HIR::TypeRef& des_borrow_inner, ::std::function<void(::HIR::ExprNodeP& n)> cb) { const auto& sp = node_ptr->span(); + const auto& src_type = context.m_ivars.get_type(node_ptr->m_res_type); // Since this function operates on destructured &-ptrs, the dereferences have to be added behind a borrow ::HIR::ExprNodeP* node_ptr_ptr = nullptr; @@ -2994,26 +2995,33 @@ namespace { node_ptr_ptr = &p->m_value; } } - // - Otherwise, create a new borrow operation and add the dereferences + // - Otherwise, create a new borrow operation behind which the dereferences ahppen if( !node_ptr_ptr ) { DEBUG("- Coercion node isn't a borrow, adding one"); auto span = node_ptr->span(); + const auto& src_inner_ty = *src_type.m_data.as_Borrow().inner; + auto borrow_type = src_type.m_data.as_Borrow().type; + ::HIR::ExprNode_UniOp::Op op = ::HIR::ExprNode_UniOp::Op::Ref; - auto borrow_type = context.m_ivars.get_type(node_ptr->m_res_type).m_data.as_Borrow().type; switch(borrow_type) { case ::HIR::BorrowType::Shared: op = ::HIR::ExprNode_UniOp::Op::Ref; break; case ::HIR::BorrowType::Unique: op = ::HIR::ExprNode_UniOp::Op::RefMut; break; case ::HIR::BorrowType::Owned: TODO(sp, "Move borrow autoderef"); } - node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_UniOp( mv$(span), op, mv$(node_ptr) )); - node_ptr->m_res_type = ::HIR::TypeRef::new_borrow(borrow_type, des_borrow_inner.clone()); + auto inner_ty_ref = ::HIR::TypeRef::new_borrow(borrow_type, des_borrow_inner.clone()); + + // 1. Dereference (resulting in the dereferenced input type) + node_ptr = NEWNODE(src_inner_ty.clone(), span, _Deref, mv$(node_ptr)); + // 2. Borrow (resulting in the referenced output type) + node_ptr = NEWNODE(mv$(inner_ty_ref), span, _UniOp, op, mv$(node_ptr)); // - Set node pointer reference to point into the new borrow op node_ptr_ptr = &dynamic_cast< ::HIR::ExprNode_UniOp&>(*node_ptr).m_value; } else { auto borrow_type = context.m_ivars.get_type(node_ptr->m_res_type).m_data.as_Borrow().type; + // Set the result of the borrow operation to the output type node_ptr->m_res_type = ::HIR::TypeRef::new_borrow(borrow_type, des_borrow_inner.clone()); } @@ -3934,9 +3942,10 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: // - Keep a list in the ivar of what types that ivar could be equated to. DEBUG("--- Coercion checking"); for(auto it = context.link_coerce.begin(); it != context.link_coerce.end(); ) { + const auto& src_ty = (**it->right_node_ptr).m_res_type; it->left_ty = context.m_resolve.expand_associated_types( (*it->right_node_ptr)->span(), mv$(it->left_ty) ); if( check_coerce(context, *it) ) { - DEBUG("- Consumed coercion " << it->left_ty << " := " << (**it->right_node_ptr).m_res_type); + DEBUG("- Consumed coercion " << it->left_ty << " := " << src_ty); it = context.link_coerce.erase(it); } else { |