summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-13 11:40:42 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-13 11:40:42 +0800
commitb8ffa877896d09fa13a0c89aae41d9e9a5b736bb (patch)
tree19aef777e66b7cd93e89d22778081cf72b5cacde /src
parent874eb4767f6350156fff6c50851d0cf9b4e6a625 (diff)
downloadmrust-b8ffa877896d09fa13a0c89aae41d9e9a5b736bb.tar.gz
HIR Typecheck - Rough deref coercions
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_context.cpp43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 4699b0b3..08d8b0cd 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -895,7 +895,7 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " (can't coerce)");
}
}
-
+
// - If tags don't match, error
if( l_t.m_data.tag() != r_t.m_data.tag() ) {
@@ -916,6 +916,46 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
return ;
}
+ // Deref coercions 1 (when a & op is destructured and expected value is the deref)
+ if( node_ptr_ptr )
+ {
+ auto& node_ptr = *node_ptr_ptr;
+
+ // - If right has a deref chain to left, build it
+ DEBUG("Trying deref coercion " << l_t << " " << r_t);
+ if( !l_t.m_data.is_Borrow() && ! this->type_contains_ivars(l_t) && ! this->type_contains_ivars(r_t) )
+ {
+ DEBUG("Trying deref coercion (2)");
+ ::HIR::TypeRef tmp_ty;
+ const ::HIR::TypeRef* out_ty = &r_t;
+ unsigned int count = 0;
+ while( (out_ty = this->autoderef(sp, *out_ty, tmp_ty)) )
+ {
+ count += 1;
+
+ if( l_t != *out_ty ) {
+ TODO(sp, "Deref coercions " << l_t << " <- " << r_t << " (became " << *out_ty << ")");
+ }
+
+ while(count --)
+ {
+ auto span = node_ptr->span();
+ node_ptr->m_res_type = this->new_ivar_tr();
+ node_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Deref( mv$(span), mv$(node_ptr) ));
+ }
+ node_ptr->m_res_type = l_t.clone();
+
+ this->mark_change();
+ return ;
+ //auto cmp = this->compare_types(left_inner_res, *out_ty);
+ //if( cmp == ::HIR::Compare::Equal ) {
+ //
+ //}
+ }
+ }
+ }
+
+
// Type error
this->dump();
ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t);
@@ -1132,7 +1172,6 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
// Apply deref coercions
}
}
- // - If right has a deref chain to left, build it
}
this->apply_equality(sp, *l_e.inner, cb_left, *r_e.inner, cb_right, nullptr);
),