summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-06 19:21:59 +1000
committerJohn Hodge <tpg@mutabah.net>2016-07-06 19:21:59 +1000
commit39cbbbe0814ec3710510fe85d37d036dd8bc3d6b (patch)
tree6c64338106c6f98683aa048ed8cfeab863c36a70 /src
parent23a4599b64d3e1d134bf0a744588e77c4700c0a7 (diff)
downloadmrust-39cbbbe0814ec3710510fe85d37d036dd8bc3d6b.tar.gz
HIR Typecheck CS - Expand associated types before doing an equality
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp9
-rw-r--r--src/hir_typeck/helpers.cpp75
-rw-r--r--src/hir_typeck/helpers.hpp9
3 files changed, 91 insertions, 2 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 6e26b33a..1d1e7eed 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -53,6 +53,7 @@ struct Context
struct IVarPossible
{
+ // TODO: If an ivar is eliminated (i.e. has its type dropped) while its pointer is here - things will break
::std::vector<const ::HIR::TypeRef*> types;
};
@@ -1445,8 +1446,12 @@ void Context::dump() const {
void Context::equate_types(const Span& sp, const ::HIR::TypeRef& li, const ::HIR::TypeRef& ri) {
// Instantly apply equality
- const auto& l_t = this->m_ivars.get_type(li);
- const auto& r_t = this->m_ivars.get_type(ri);
+
+ // TODO: Check if the type contains a replacable associated type
+ ::HIR::TypeRef l_tmp;
+ ::HIR::TypeRef r_tmp;
+ const auto& l_t = this->m_resolve.expand_associated_types(sp, this->m_ivars.get_type(li), l_tmp);
+ const auto& r_t = this->m_resolve.expand_associated_types(sp, this->m_ivars.get_type(ri), r_tmp);
DEBUG("- l_t = " << l_t << ", r_t = " << r_t);
TU_IFLET(::HIR::TypeRef::Data, r_t.m_data, Infer, r_e,
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index a44d8608..0d541808 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -910,6 +910,81 @@ void TraitResolution::compact_ivars(HMTypeInferrence& m_ivars)
}
}
+bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const
+{
+ //TRACE_FUNCTION_F(input);
+ TU_MATCH(::HIR::TypeRef::Data, (input.m_data), (e),
+ (Infer,
+ auto& ty = this->m_ivars.get_type(input);
+ if( ty != input ) {
+ return this->has_associated_type(ty);
+ }
+ return false;
+ ),
+ (Diverge,
+ return false;
+ ),
+ (Primitive,
+ return false;
+ ),
+ (Path,
+ TU_MATCH(::HIR::Path::Data, (e.path.m_data), (e2),
+ (Generic,
+ bool rv = false;
+ for(const auto& arg : e2.m_params.m_types)
+ rv |= has_associated_type(arg);
+ return rv;
+ ),
+ (UfcsInherent,
+ TODO(Span(), "Path - UfcsInherent - " << e.path);
+ ),
+ (UfcsKnown,
+ // - Only try resolving if the binding isn't known
+ if( !e.binding.is_Unbound() )
+ return false;
+ return true;
+ ),
+ (UfcsUnknown,
+ BUG(Span(), "Encountered UfcsUnknown");
+ )
+ )
+ ),
+ (Generic,
+ return false;
+ ),
+ (TraitObject,
+ // Recurse?
+ ),
+ (Array,
+ return has_associated_type(*e.inner);
+ ),
+ (Slice,
+ return has_associated_type(*e.inner);
+ ),
+ (Tuple,
+ bool rv = false;
+ for(const auto& sub : e) {
+ rv |= has_associated_type(sub);
+ }
+ return rv;
+ ),
+ (Borrow,
+ return has_associated_type(*e.inner);
+ ),
+ (Pointer,
+ return has_associated_type(*e.inner);
+ ),
+ (Function,
+ // Recurse?
+ return false;
+ ),
+ (Closure,
+ // Recurse?
+ return false;
+ )
+ )
+ BUG(Span(), "Fell off the end of has_associated_type - input=" << input);
+}
::HIR::TypeRef TraitResolution::expand_associated_types(const Span& sp, ::HIR::TypeRef input) const
{
TRACE_FUNCTION_F(input);
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index 9c3a110b..93fe8cf9 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -133,8 +133,17 @@ public:
/// Check if a trait bound applies, using the passed function to expand Generic/Infer types
bool check_trait_bound(const Span& sp, const ::HIR::TypeRef& type, const ::HIR::GenericPath& trait, t_cb_generic placeholder) const;
+ bool has_associated_type(const ::HIR::TypeRef& ty) const;
/// Expand any located associated types in the input, operating in-place and returning the result
::HIR::TypeRef expand_associated_types(const Span& sp, ::HIR::TypeRef input) const;
+ const ::HIR::TypeRef& expand_associated_types(const Span& sp, const ::HIR::TypeRef& input, ::HIR::TypeRef& tmp) const {
+ if( this->has_associated_type(input) ) {
+ return (tmp = this->expand_associated_types(sp, input.clone()));
+ }
+ else {
+ return input;
+ }
+ }
/// Iterate over in-scope bounds (function then top)
bool iterate_bounds( ::std::function<bool(const ::HIR::GenericBound&)> cb) const;