summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 1f6dccdc..45de4850 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -4935,6 +4935,31 @@ namespace {
return context.m_ivars.types_equal(*s_e.inner, *d_e.inner);
}
}
+
+ if( dst.m_data.is_Pointer() && src.m_data.is_Pointer() ) {
+ const auto& d_e = dst.m_data.as_Pointer();
+ const auto& s_e = src.m_data.as_Pointer();
+ // Higher = more specific (e.g. Unique > Shared)
+ if( s_e.type < d_e.type ) {
+ return false;
+ }
+ else if( s_e.type == d_e.type ) {
+ // Check relationship
+ // - 1. Deref chain.
+ // - 2. Trait object?
+ }
+ else {
+ return context.m_ivars.types_equal(*s_e.inner, *d_e.inner);
+ }
+ }
+
+ if( dst.m_data.is_Pointer() && src.m_data.is_Borrow() ) {
+ const auto& d_e = dst.m_data.as_Pointer();
+ const auto& s_e = src.m_data.as_Borrow();
+ if( s_e.type == d_e.type ) {
+ return context.m_ivars.types_equal(*s_e.inner, *d_e.inner);
+ }
+ }
return false;
}
@@ -5011,6 +5036,28 @@ namespace {
#endif
// Prefer cases where this type is being created from a known type
+ if( ivar_ent.types_from.size() == 0 && ivar_ent.types_to.size() == 0 ) {
+ ivar_ent.reset();
+ return ;
+ }
+ DEBUG("-- " << ty_l << " FROM=" << ivar_ent.types_from << ", TO=" << ivar_ent.types_to);
+
+ #if 1
+ if( ivar_ent.types_from.size() == 1 && ivar_ent.types_to.size() == 1 ) {
+ const auto& ty_to = ivar_ent.types_to[0];
+ const auto& ty_from = ivar_ent.types_from[0];
+ if( H::can_coerce_to(context, ty_to, ty_from) )
+ {
+ // Only one possibility
+ DEBUG("- IVar " << ty_l << " = " << ty_to << " (to)");
+ context.equate_types(sp, ty_l, ty_to);
+
+ ivar_ent.reset();
+ return ;
+ }
+ }
+ //else
+ #endif
if( ivar_ent.types_from.size() == 1 ) {
//const ::HIR::TypeRef& ty_r = *ivar_ent.types_from[0];
const ::HIR::TypeRef& ty_r = ivar_ent.types_from[0];