summaryrefslogtreecommitdiff
path: root/src/hir_typeck
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-05-14 23:21:46 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-05-14 23:21:46 +0800
commit3a3f95d0c0b64ae2c5c702a50f6d26a35931bf48 (patch)
tree9c764a970a88c1a809933162b8eed00545391ad9 /src/hir_typeck
parent699dbed9dca998b0df8418fde68235d230a726eb (diff)
downloadmrust-3a3f95d0c0b64ae2c5c702a50f6d26a35931bf48.tar.gz
HIR Typecheck - Fix (hopefully) typeck errors in new libcollections
Diffstat (limited to 'src/hir_typeck')
-rw-r--r--src/hir_typeck/expr_cs.cpp72
1 files changed, 62 insertions, 10 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 12819251..52af3924 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -4986,8 +4986,28 @@ namespace {
else {
// No equivalence added
}
- // - Fall through and search for the impl
- DEBUG("- Unsize, no ivar equivalence");
+
+ // TODO: If this was a compiler-inserted bound (from a coercion rule), then do deref checks
+#if 0
+ {
+ ::HIR::TypeRef tmp_ty;
+ const ::HIR::TypeRef* ty_ptr = &src_ty;
+ while( (ty_ptr = context.m_resolve.autoderef(sp, *ty_ptr, tmp_ty)) )
+ {
+ const auto& cur_ty = context.m_ivars.get_type(*ty_ptr);
+ if( cur_ty.m_data.is_Infer() ) {
+ break;
+ }
+ auto cmp = dst_ty.compare_with_placeholders(sp, cur_ty, context.m_ivars.callback_resolve_infer());
+ if( cmp != ::HIR::Compare::Unequal )
+ {
+ // TODO: This is a deref coercion, so what can actually be done?
+ TODO(sp, "Handle Unsize with deref - " << src_ty << " -> " << dst_ty);
+ }
+ }
+ }
+#endif
+ DEBUG("- Unsize, no deref or ivar");
}
if( v.trait == context.m_crate.get_lang_item_path(sp, "coerce_unsized") )
{
@@ -5052,7 +5072,7 @@ namespace {
// > This makes `let v: usize = !0;` work without special cases
auto cmp2 = v.left_ty.compare_with_placeholders(sp, out_ty, context.m_ivars.callback_resolve_infer());
if( cmp2 == ::HIR::Compare::Unequal ) {
- DEBUG("- (fail) known result can't match (" << context.m_ivars.fmt_type(v.left_ty) << " and " << context.m_ivars.fmt_type(out_ty) << ")");
+ DEBUG("[check_associated] - (fail) known result can't match (" << context.m_ivars.fmt_type(v.left_ty) << " and " << context.m_ivars.fmt_type(out_ty) << ")");
return false;
}
// if solid or fuzzy, leave as-is
@@ -5071,9 +5091,10 @@ namespace {
}
else {
count += 1;
- DEBUG("- (possible) " << impl);
+ DEBUG("[check_associated] - (possible) " << impl);
if( possible_impl_ty == ::HIR::TypeRef() ) {
+ DEBUG("[check_associated] First - " << impl);
possible_impl_ty = impl.get_impl_type();
possible_params = impl.get_trait_params();
best_impl = mv$(impl);
@@ -5084,27 +5105,33 @@ namespace {
// NOTE: `overlaps_with` (should be) reflective
else if( impl.overlaps_with(best_impl) )
{
- DEBUG("- overlaps with " << best_impl);
+ DEBUG("[check_associated] - Overlaps with existing - " << best_impl);
+ // if not more specific than the existing best, ignore.
if( ! impl.more_specific_than(best_impl) )
{
- possible_impl_ty = impl.get_impl_type();
- possible_params = impl.get_trait_params();
- best_impl = mv$(impl);
+ // Ignore
+ DEBUG("[check_associated] - Less specific than existing");
count -= 1;
}
+ // If the existing best is not more specific than the new one, use the new one
else if( ! best_impl.more_specific_than(impl) )
{
- // Ignore
+ DEBUG("[check_associated] - More specific than existing - " << impl);
+ possible_impl_ty = impl.get_impl_type();
+ possible_params = impl.get_trait_params();
+ best_impl = mv$(impl);
count -= 1;
}
else
{
- DEBUG("> Neither is more specific. Error?");
+ // Supposedly, `more_specific_than` should be reflexive...
+ DEBUG("[check_associated] > Neither is more specific. Error?");
}
}
else
{
// Disjoint impls.
+ DEBUG("[check_associated] Disjoint impl -" << impl);
}
#endif
@@ -5680,6 +5707,31 @@ namespace {
// TODO: Monomorphise this type replacing mentions of the current ivar with the replacement?
+#if 0 // NOTE: The following shouldn't happen
+ if( bound.trait == context.m_crate.get_lang_item_path(sp, "unsize") /* && bound.is_from_coerce*/ )
+ {
+ bool possible = false;
+
+ ::HIR::TypeRef tmp_ty;
+ const ::HIR::TypeRef* ty_ptr = &new_ty;
+ while( (ty_ptr = context.m_resolve.autoderef(sp, *ty_ptr, tmp_ty)) )
+ {
+ const auto& cur_ty = context.get_type(*ty_ptr);
+ if( cur_ty.m_data.is_Infer() ) {
+ break;
+ }
+ auto cmp = ty_l.compare_with_placeholders(sp, cur_ty, context.m_ivars.callback_resolve_infer());
+ if( cmp != ::HIR::Compare::Unequal )
+ {
+ possible = true;
+ break;
+ }
+ }
+ if( possible )
+ continue ;
+ }
+#endif
+
// Search for any trait impl that could match this,
bool has = context.m_resolve.find_trait_impls(sp, bound.trait, bound.params, new_ty, [&](const auto , auto){return true;});
if( !has ) {