diff options
author | John Hodge <tpg@mutabah.net> | 2016-07-10 16:15:29 +1000 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-07-10 16:15:29 +1000 |
commit | c6b76c4d3612e3029767fbf08c09f2986e90d11a (patch) | |
tree | e56edccf453de24661c96e36cf91d8f6fe31d3ff /src | |
parent | 58f02a54af41fcd4c035cb21ed5051c9a87556ae (diff) | |
download | mrust-c6b76c4d3612e3029767fbf08c09f2986e90d11a.tar.gz |
HIR Typecheck CS - (EVIL) Propagate type bounds through to supertraits
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 6 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 26 | ||||
-rw-r--r-- | src/hir_typeck/helpers.hpp | 1 |
3 files changed, 29 insertions, 4 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 38a7a21d..3081a366 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -321,8 +321,12 @@ namespace { // TODO: Either - Don't include the above impl bound, or change the below trait to the one that has that type for( const auto& assoc : be.trait.m_type_bounds ) { + ::HIR::GenericPath type_trait_path; + context.m_resolve.trait_contains_type(sp, real_trait, *be.trait.m_trait_ptr, assoc.first, type_trait_path); + auto other_ty = monomorphise_type_with(sp, assoc.second, cache.m_monomorph_cb, true); - context.equate_types_assoc(sp, other_ty, trait_path, mv$(trait_params.clone().m_types), real_type, assoc.first.c_str()); + + context.equate_types_assoc(sp, other_ty, type_trait_path.m_path, mv$(type_trait_path.m_params.m_types), real_type, assoc.first.c_str()); } ), (TypeEquality, diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index cd2a8979..1908a884 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -983,6 +983,8 @@ bool TraitResolution::find_trait_impls(const Span& sp, // NOTE: This is a conditional "true", we know nothing about the move/mut-ness of this closure yet // - Could we? + + ::HIR::PathParams pp; pp.m_types.push_back( ::HIR::TypeRef(mv$(args)) ); ::std::map< ::std::string, ::HIR::TypeRef> types; @@ -1518,7 +1520,27 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple return true; } } - if( this->find_named_trait_in_trait(sp, trait,params, *e.trait.m_trait_ptr, e.trait.m_path.m_path, e.trait.m_path.m_params, type, callback) ) { + // HACK: The wrapping closure takes associated types from this bound and applies them to the returned set + // - XXX: This is actually wrong (false-positive) in many cases. FIXME + bool rv = this->find_named_trait_in_trait(sp, + trait,params, + *e.trait.m_trait_ptr, e.trait.m_path.m_path,e.trait.m_path.m_params, + type, + [&](const auto& ty, const auto& params, const auto& assoc) { + // TODO: Avoid duplicating this map every time + ::std::map< ::std::string,::HIR::TypeRef> assoc2; + for(const auto& i : assoc) { + assoc2.insert( ::std::make_pair(i.first, i.second.clone()) ); + } + for(const auto& i : e.trait.m_type_bounds) { + // TODO: Only include from above when needed + //if( des_trait_ref.m_types.count(i.first) ) { + assoc2.insert( ::std::make_pair(i.first, i.second.clone()) ); + //} + } + return callback(ty, params, assoc2); + }); + if( rv ) { return true; } } @@ -1558,7 +1580,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple } else { if( ge.binding >= assoc_info->trait.m_params.m_types.size() ) - BUG(sp, "find_named_trait_in_trait - Generic #" << ge.binding << " " << ge.name << " out of range"); + BUG(sp, "find_trait_impls_bound - Generic #" << ge.binding << " " << ge.name << " out of range"); return assoc_info->trait.m_params.m_types[ge.binding]; } }, false); diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp index a0668c28..94fcef6b 100644 --- a/src/hir_typeck/helpers.hpp +++ b/src/hir_typeck/helpers.hpp @@ -199,7 +199,6 @@ public: const ::HIR::TypeRef* autoderef(const Span& sp, const ::HIR::TypeRef& ty, ::HIR::TypeRef& tmp_type) const; bool find_field(const Span& sp, const ::HIR::TypeRef& ty, const ::std::string& name, /* Out -> */::HIR::TypeRef& field_type) const; -private: bool find_method(const Span& sp, const HIR::t_trait_list& traits, const ::HIR::TypeRef& ty, const ::std::string& method_name, /* Out -> */::HIR::Path& fcn_path) const; /// Locates a named method in a trait, and returns the path of the trait that contains it (with fixed parameters) |