summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-23 15:16:37 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-23 15:16:37 +0800
commitb6600a06ab403caa58a9938e677816fa5d48e1c6 (patch)
tree5ba91ff7521604f33137e90cd5a71575a9898bf3
parent28b1e61bd288a0e55cc0c6cb2d6c98be6983b0a1 (diff)
downloadmrust-b6600a06ab403caa58a9938e677816fa5d48e1c6.tar.gz
HIR Typecheck Expressions - Another ivar guess rule
-rw-r--r--src/hir_typeck/expr_cs.cpp32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 157ae6ae..5c06d11d 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -5130,6 +5130,7 @@ namespace {
return context.m_ivars.types_equal(a, b);
}
+ // TODO: `can_unsize_to`
static bool can_coerce_to(const Context& context, const ::HIR::TypeRef& dst, const ::HIR::TypeRef& src) {
if( dst.m_data.is_Infer() )
return false;
@@ -5368,7 +5369,36 @@ namespace {
return DedupKeep::Both;
});
- // TODO: If there is a type that appears on both sides, pick it?
+
+ // If there's one option for both desination types, and nothing for the source ...
+ if( ivar_ent.types_coerce_to.size() == 1 && ivar_ent.types_unsize_to.size() == 1 && ivar_ent.types_coerce_from.empty() && ivar_ent.types_unsize_from.empty() )
+ {
+ // And the coercion can unsize to the unsize, pick the coercion (it's valid, the other way around isn't)
+ // TODO: Use a `can_unsize_to` functon instead (that handles Unsize as well as Deref)
+ if( H::type_derefs_from(sp, context, ivar_ent.types_unsize_to[0], ivar_ent.types_coerce_to[0]) )
+ {
+ const auto& new_ty = ivar_ent.types_coerce_to[0];
+ DEBUG("- IVar " << ty_l << " = " << new_ty << " (unsize to)");
+ context.equate_types(sp, ty_l, new_ty);
+ ivar_ent.reset();
+ return ;
+ }
+ }
+ #if 0
+ // If there's only one coerce and unsize from, ...
+ if( ivar_ent.types_coerce_from.size() == 1 && ivar_ent.types_unsize_from.size() == 1 && ivar_ent.types_coerce_to.empty() && ivar_ent.types_unsize_to.empty() )
+ {
+ // and if the coerce can unsize to the unsize target.
+ if( H::can_coerce_to(context, ivar_ent.types_unsize_from[0], ivar_ent.types_coerce_from[0]) )
+ {
+ const auto& new_ty = ivar_ent.types_coerce_from[0];
+ DEBUG("- IVar " << ty_l << " = " << new_ty << " (coerce from)");
+ context.equate_types(sp, ty_l, new_ty);
+ ivar_ent.reset();
+ return ;
+ }
+ }
+ #endif
// HACK: Merge into a single lists
::std::vector< ::HIR::TypeRef> types_from_o;