summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-10 14:35:51 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-10 14:35:51 +0800
commit45082a3c953c6acfce103cdc4e0bd4ed8c3b46f0 (patch)
tree3b10347eb51868bbbc6cd8fa622518df52cec8d7
parentec93160044546d12bceaa95c8a5b0d6d7dd534ee (diff)
downloadmrust-45082a3c953c6acfce103cdc4e0bd4ed8c3b46f0.tar.gz
HIR Typecheck - Recursively expand associated types
-rw-r--r--src/hir_typeck/expr.cpp7
-rw-r--r--src/hir_typeck/expr_context.cpp8
2 files changed, 9 insertions, 6 deletions
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index 4a1a729f..9afe07fc 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -1490,10 +1490,11 @@ namespace typeck {
TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e),
(Infer,
auto new_ty = this->context.get_type(ty).clone();
- if( new_ty.m_data.is_Infer() ) {
- ERROR(sp, E0000, "Failed to infer type " << new_ty << " in " << top_type);
- }
+ // - Move over before checking, so that the source type mentions the correct ivar
ty = mv$(new_ty);
+ if( ty.m_data.is_Infer() ) {
+ ERROR(sp, E0000, "Failed to infer type " << ty << " in " << top_type);
+ }
check_type_resolved(sp, ty, top_type);
),
(Diverge,
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index efcf3549..5a6ec5ad 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -644,7 +644,7 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
assert( ! left.m_data.is_Infer() || left.m_data.as_Infer().index != ~0u );
assert( !right.m_data.is_Infer() || right.m_data.as_Infer().index != ~0u );
// - Convert left/right types into resolved versions (either root ivar, or generic replacement)
- const auto& l_t1 = left.m_data.is_Generic() ? cb_left (left ) : this->get_type(left );
+ const auto& l_t1 = left .m_data.is_Generic() ? cb_left (left ) : this->get_type(left );
const auto& r_t1 = right.m_data.is_Generic() ? cb_right(right) : this->get_type(right);
if( l_t1 == r_t1 ) {
return ;
@@ -654,6 +654,9 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
const auto& l_t = this->expand_associated_types_to(sp, l_t1, left_tmp);
::HIR::TypeRef right_tmp;
const auto& r_t = this->expand_associated_types_to(sp, r_t1, right_tmp);
+ if( l_t == r_t ) {
+ return ;
+ }
DEBUG("- l_t = " << l_t << ", r_t = " << r_t);
TU_IFLET(::HIR::TypeRef::Data, r_t.m_data, Infer, r_e,
@@ -987,7 +990,6 @@ bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait,
),
(UfcsKnown,
DEBUG("Locating associated type for " << e.path);
- // TODO: Use the marker `e.binding` to tell if it's worth trying
*e2.type = expand_associated_types(sp, mv$(*e2.type));
@@ -1150,7 +1152,7 @@ bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait,
return *impl_args[ge.binding];
});
DEBUG("Converted UfcsKnown - " << e.path << " = " << new_type << " using " << e2.item << " = " << impl_ptr->m_types.at( e2.item ));
- return new_type;
+ return expand_associated_types(sp, mv$(new_type));
}
// TODO: If there are no ivars in this path, set its binding to Opaque