diff options
author | John Hodge <tpg@mutabah.net> | 2016-07-06 19:21:59 +1000 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-07-06 19:21:59 +1000 |
commit | 39cbbbe0814ec3710510fe85d37d036dd8bc3d6b (patch) | |
tree | 6c64338106c6f98683aa048ed8cfeab863c36a70 /src | |
parent | 23a4599b64d3e1d134bf0a744588e77c4700c0a7 (diff) | |
download | mrust-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.cpp | 9 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 75 | ||||
-rw-r--r-- | src/hir_typeck/helpers.hpp | 9 |
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; |