summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-12 21:53:19 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-12 21:53:19 +0800
commit4bfcf255fa80cd0635bf6457aa9b5230fa0b3509 (patch)
tree75b0a3ae9f912a4f3629f2488bc02baeb3fa0ff8
parentec8ade6675dcfac39c74cbf06871247f532a558f (diff)
downloadmrust-4bfcf255fa80cd0635bf6457aa9b5230fa0b3509.tar.gz
HIR Typecheck - &mut -> & reborrow
-rw-r--r--src/hir_typeck/expr_context.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 4d7980ad..3044379b 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -1007,6 +1007,25 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
}
),
(Borrow,
+ // If using `&mut T` where `&const T` is expected - insert a reborrow (&*)
+ if( l_e.type == ::HIR::BorrowType::Shared && r_e.type == ::HIR::BorrowType::Unique && node_ptr_ptr ) {
+ this->apply_equality(sp, *l_e.inner, cb_left, *r_e.inner, cb_right, nullptr);
+
+ // Add cast down
+ auto& node_ptr = *node_ptr_ptr;
+
+ auto span = node_ptr->span();
+ // *<inner>
+ node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Deref(mv$(span), mv$(node_ptr)));
+ node_ptr->m_res_type = l_e.inner->clone();
+ // &*<inner>
+ node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_UniOp(mv$(span), ::HIR::ExprNode_UniOp::Op::Ref, mv$(node_ptr)));
+ node_ptr->m_res_type = l_t.clone();
+
+ this->mark_change();
+ return ;
+ }
+
if( l_e.type != r_e.type ) {
// TODO: This could be allowed if left == Shared && right == Unique (reborrowing)
ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - Borrow classes differ");