diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-06-09 20:31:41 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-06-09 20:31:41 +0800 |
commit | a9f501bde9d8ff5e714d0ef2663177b0949f95cc (patch) | |
tree | 47189972d96bb44e2111e707987aabf75f9e3872 | |
parent | 8992eaa470e27ed3da396aed41ce741bc509bb0f (diff) | |
download | mrust-a9f501bde9d8ff5e714d0ef2663177b0949f95cc.tar.gz |
HIR - Sort trait impls too
-rw-r--r-- | src/hir/deserialise.cpp | 17 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 10 | ||||
-rw-r--r-- | src/hir/hir.hpp | 39 | ||||
-rw-r--r-- | src/hir/hir_ops.cpp | 145 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 13 | ||||
-rw-r--r-- | src/hir/type.hpp | 18 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 47 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs_outer.cpp | 76 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 14 | ||||
-rw-r--r-- | src/trans/auto_impls.cpp | 6 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 155 |
11 files changed, 308 insertions, 232 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 9d5b6cd2..f2794f29 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -839,6 +839,14 @@ template<> DEF_D( ::MacroRulesPtr, return d.deserialise_macrorulesptr(); ) template<> DEF_D( unsigned int, return static_cast<unsigned int>(d.deserialise_count()); ) + template<typename T> + DEF_D( ::HIR::Crate::ImplGroup<T>, + ::HIR::Crate::ImplGroup<T> rv; + rv.named = d.deserialise_pathmap< ::std::vector<T>>(); + rv.non_named = d.deserialise_vec<T>(); + rv.generic = d.deserialise_vec<T>(); + return rv; + ) template<> DEF_D( ::HIR::ExternLibrary, return d.deserialise_extlib(); ) ::HIR::LifetimeDef HirDeserialiser::deserialise_lifetimedef() @@ -1325,12 +1333,9 @@ rv.m_crate_name = this->m_crate_name; rv.m_root_module = deserialise_module(); - rv.m_named_type_impls = deserialise_pathmap< ::std::vector<::HIR::TypeImpl>>(); - rv.m_primitive_type_impls = deserialise_vec< ::HIR::TypeImpl>(); - rv.m_generic_type_impls = deserialise_vec< ::HIR::TypeImpl>(); - - rv.m_trait_impls = deserialise_pathmap< ::std::vector<::HIR::TraitImpl>>(); - rv.m_marker_impls = deserialise_pathmap< ::std::vector<::HIR::MarkerImpl>>(); + rv.m_type_impls = D< ::HIR::Crate::ImplGroup<::HIR::TypeImpl> >::des(*this); + rv.m_trait_impls = deserialise_pathmap< ::HIR::Crate::ImplGroup<::HIR::TraitImpl>>(); + rv.m_marker_impls = deserialise_pathmap< ::HIR::Crate::ImplGroup<::HIR::MarkerImpl>>(); rv.m_exported_macros = deserialise_istrumap< ::MacroRulesPtr>(); rv.m_lang_items = deserialise_strumap< ::HIR::SimplePath>(); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index cb8438bf..0ad59d56 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1676,7 +1676,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ) } - hir_crate.m_trait_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::TraitImpl>()) ).first->second.push_back( ::HIR::TraitImpl { + // Sorted later on + hir_crate.m_trait_impls[mv$(trait_name)].generic.push_back( ::HIR::TraitImpl { mv$(params), mv$(trait_args), mv$(type), @@ -1696,7 +1697,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat else { auto type = LowerHIR_Type(impl.def().type()); - hir_crate.m_marker_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::MarkerImpl>()) ).first->second.push_back(::HIR::MarkerImpl { + hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(::HIR::MarkerImpl { mv$(params), mv$(trait_args), true, @@ -1750,7 +1751,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } // Sorted later on - hir_crate.m_generic_type_impls.push_back( ::HIR::TypeImpl { + hir_crate.m_type_impls.generic.push_back( ::HIR::TypeImpl { mv$(params), mv$(type), mv$(methods), @@ -1771,7 +1772,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat auto trait_name = mv$(trait.m_path); auto trait_args = mv$(trait.m_params); - hir_crate.m_marker_impls.insert( ::std::make_pair(mv$(trait_name), ::std::vector<::HIR::MarkerImpl>()) ).first->second.push_back(::HIR::MarkerImpl { + // Sorting done later + hir_crate.m_marker_impls[mv$(trait_name)].generic.push_back(::HIR::MarkerImpl { mv$(params), mv$(trait_args), false, diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 12b874a7..2169c0c3 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -527,17 +527,46 @@ public: Module m_root_module; + template<typename T> + struct ImplGroup + { + ::std::map<::HIR::SimplePath, ::std::vector<T>> named; + ::std::vector<T> non_named; // TODO: use a map of HIR::TypeRef::Data::Tag + ::std::vector<T> generic; + + const ::std::vector<T>* get_list_for_type(const ::HIR::TypeRef& ty) const { + static ::std::vector<T> empty; + if( const auto* p = ty.get_sort_path() ) { + auto it = named.find(*p); + if( it != named.end() ) + return &it->second; + else + return nullptr; + } + else { + // TODO: Sort these by type tag, use the `Primitive` group if `ty` is Infer + return &non_named; + } + } + ::std::vector<T>& get_list_for_type_mut(const ::HIR::TypeRef& ty) { + if( const auto* p = ty.get_sort_path() ) { + return named[*p]; + } + else { + // TODO: Ivars match with core types + return non_named; + } + } + }; /// Impl blocks on just a type, split into three groups // - Named type (sorted on the path) // - Primitive types // - Unsorted (generics, and everything before outer type resolution) - ::std::map<::HIR::SimplePath, ::std::vector<::HIR::TypeImpl>> m_named_type_impls; - ::std::vector< ::HIR::TypeImpl> m_primitive_type_impls; - ::std::vector< ::HIR::TypeImpl> m_generic_type_impls; + ImplGroup<::HIR::TypeImpl> m_type_impls; /// Impl blocks - ::std::map< ::HIR::SimplePath, ::std::vector<::HIR::TraitImpl> > m_trait_impls; - ::std::map< ::HIR::SimplePath, ::std::vector<::HIR::MarkerImpl> > m_marker_impls; + ::std::map< ::HIR::SimplePath, ImplGroup<::HIR::TraitImpl> > m_trait_impls; + ::std::map< ::HIR::SimplePath, ImplGroup<::HIR::MarkerImpl> > m_marker_impls; /// Macros exported by this crate ::std::unordered_map< RcString, ::MacroRulesPtr > m_exported_macros; diff --git a/src/hir/hir_ops.cpp b/src/hir/hir_ops.cpp index 9e867980..14533fb4 100644 --- a/src/hir/hir_ops.cpp +++ b/src/hir/hir_ops.cpp @@ -935,45 +935,60 @@ bool ::HIR::TraitImpl::overlaps_with(const Crate& crate, const ::HIR::TraitImpl& } } -bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TraitImpl&)> callback) const +namespace { - auto it = this->m_trait_impls.find( trait ); - if( it != this->m_trait_impls.end() ) + template<typename ImplType> + bool find_impls_list(const ::std::vector<ImplType>& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function<bool(const ImplType&)> callback) { - for(const auto& impl : it->second) + for(const auto& impl : impl_list) { - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { + if( impl.matches_type(type, ty_res) ) + { + if( callback(impl) ) + { return true; } } } + return false; } - for( const auto& ec : this->m_ext_crates ) - { - if( ec.second.m_data->find_trait_impls(trait, type, ty_res, callback) ) { - return true; - } - } - return false; } -bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::MarkerImpl&)> callback) const +namespace { - auto it = this->m_marker_impls.find( trait ); - if( it != this->m_marker_impls.end() ) + bool find_trait_impls_int( + const ::HIR::Crate& crate, const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, + ::HIR::t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TraitImpl&)> callback + ) { - for(const auto& impl : it->second) + auto it = crate.m_trait_impls.find( trait ); + if( it != crate.m_trait_impls.end() ) { - if( impl.matches_type(type, ty_res) ) { - if( callback(impl) ) { + // 1. Find named impls (associated with named types) + if( const auto* impl_list = it->second.get_list_for_type(type) ) + { + if( find_impls_list(*impl_list, type, ty_res, callback) ) return true; - } } + + // 2. Search fully generic list. + if( find_impls_list(it->second.generic, type, ty_res, callback) ) + return true; } + + return false; + } +} + +bool ::HIR::Crate::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TraitImpl&)> callback) const +{ + if( find_trait_impls_int(*this, trait, type, ty_res, callback) ) + { + return true; } for( const auto& ec : this->m_ext_crates ) { - if( ec.second.m_data->find_auto_trait_impls(trait, type, ty_res, callback) ) { + if( find_trait_impls_int(*ec.second.m_data, trait, type, ty_res, callback) ) + { return true; } } @@ -981,46 +996,57 @@ bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const : } namespace { - bool find_type_impls_list(const ::std::vector<HIR::TypeImpl>& impl_list, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TypeImpl&)> callback) + bool find_auto_trait_impls_int( + const ::HIR::Crate& crate, const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, + ::HIR::t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::MarkerImpl&)> callback + ) { - for(const auto& impl : impl_list) + auto it = crate.m_marker_impls.find( trait ); + if( it != crate.m_marker_impls.end() ) { - if( impl.matches_type(type, ty_res) ) + // 1. Find named impls (associated with named types) + if( const auto* impl_list = it->second.get_list_for_type(type) ) { - if( callback(impl) ) - { + if( find_impls_list(*impl_list, type, ty_res, callback) ) return true; - } } + + // 2. Search fully generic list. + if( find_impls_list(it->second.generic, type, ty_res, callback) ) + return true; } + return false; } - bool find_type_impls_int(const ::HIR::Crate& crate, const ::HIR::SimplePath* sort_path, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TypeImpl&)> callback) +} +bool ::HIR::Crate::find_auto_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::MarkerImpl&)> callback) const +{ + if( find_auto_trait_impls_int(*this, trait, type, ty_res, callback) ) + { + return true; + } + for( const auto& ec : this->m_ext_crates ) { - // 1. Find named impls (associated with named types) - if( sort_path ) + if( find_auto_trait_impls_int(*ec.second.m_data, trait, type, ty_res, callback) ) { - // TODO: This fails if the type is marked as #[fundamental] - //if( sort_path->m_crate_name != crate.m_crate_name ) { - // return false; - //} - - auto impl_list_it = crate.m_named_type_impls.find(*sort_path); - if( impl_list_it != crate.m_named_type_impls.end() ) - { - if( find_type_impls_list(impl_list_it->second, type, ty_res, callback) ) - return true; - } + return true; } - // - If this type has no associated path, look in the primitives list - else + } + return false; +} +namespace +{ + bool find_type_impls_int(const ::HIR::Crate& crate, const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TypeImpl&)> callback) + { + // 1. Find named impls (associated with named types) + if( const auto* impl_list = crate.m_type_impls.get_list_for_type(type) ) { - if( find_type_impls_list(crate.m_primitive_type_impls, type, ty_res, callback) ) + if( find_impls_list(*impl_list, type, ty_res, callback) ) return true; } // 2. Search fully generic list? - if( find_type_impls_list(crate.m_generic_type_impls, type, ty_res, callback) ) + if( find_impls_list(crate.m_type_impls.generic, type, ty_res, callback) ) return true; return false; @@ -1028,40 +1054,15 @@ namespace } bool ::HIR::Crate::find_type_impls(const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TypeImpl&)> callback) const { - const ::HIR::SimplePath* path = nullptr; - // - Generic paths get sorted - if( TU_TEST1(type.m_data, Path, .path.m_data.is_Generic()) ) - { - path = &type.m_data.as_Path().path.m_data.as_Generic().m_path; - } - // - So do trait objects - else if( type.m_data.is_TraitObject() ) - { - path = &type.m_data.as_TraitObject().m_trait.m_path.m_path; - } - else - { - // Keep as nullptr, will search primitive list - } - - if( path ) - { - DEBUG(type << ", path=" << *path); - } - else - { - DEBUG(type << ", no path"); - } - // > Current crate - if( find_type_impls_int(*this, path, type, ty_res, callback) ) + if( find_type_impls_int(*this, type, ty_res, callback) ) { return true; } for( const auto& ec : this->m_ext_crates ) { //DEBUG("- " << ec.first); - if( find_type_impls_int(*ec.second.m_data, path, type, ty_res, callback) ) + if( find_type_impls_int(*ec.second.m_data, type, ty_res, callback) ) { return true; } diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 83e6d016..7725d49f 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -308,17 +308,20 @@ serialise(pm.path); serialise_vec(pm.attributes); } + template<typename T> + void serialise(const ::HIR::Crate::ImplGroup<T>& ig) + { + serialise_pathmap(ig.named); + serialise_vec(ig.non_named); + serialise_vec(ig.generic); + } void serialise_crate(const ::HIR::Crate& crate) { m_out.write_string(crate.m_crate_name); serialise_module(crate.m_root_module); - //std::map<HIR::SimplePath,std::vector<TypeImpl>> - serialise_pathmap(crate.m_named_type_impls); - serialise_vec(crate.m_primitive_type_impls); - serialise_vec(crate.m_generic_type_impls); - + serialise(crate.m_type_impls); serialise_pathmap(crate.m_trait_impls); serialise_pathmap(crate.m_marker_impls); diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 7a5a0a1c..13300bbc 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -328,6 +328,24 @@ public: // Compares this type with another, using `resolve_placeholder` to get replacements for generics/infers in `x` Compare compare_with_placeholders(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder) const; + + const ::HIR::SimplePath* get_sort_path() const { + // - Generic paths get sorted + if( TU_TEST1(this->m_data, Path, .path.m_data.is_Generic()) ) + { + return &this->m_data.as_Path().path.m_data.as_Generic().m_path; + } + // - So do trait objects + else if( this->m_data.is_TraitObject() ) + { + return &this->m_data.as_TraitObject().m_trait.m_path.m_path; + } + else + { + // Keep as nullptr, will search primitive list + return nullptr; + } + } }; extern ::std::ostream& operator<<(::std::ostream& os, const ::HIR::TypeRef& ty); diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 8bf674b3..1cc54090 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -12,38 +12,39 @@ { } +namespace { + template<typename T> + void visit_impls(::HIR::Crate::ImplGroup<T>& g, ::std::function<void(T&)> cb) { + for( auto& impl_group : g.named ) + { + for( auto& impl : impl_group.second ) + { + cb(impl); + } + } + for( auto& impl : g.non_named ) + { + cb(impl); + } + for( auto& impl : g.generic ) + { + cb(impl); + } + } +} + void ::HIR::Visitor::visit_crate(::HIR::Crate& crate) { this->visit_module(::HIR::ItemPath(crate.m_crate_name), crate.m_root_module ); - for( auto& ty_impl_group : crate.m_named_type_impls ) - { - for( auto& ty_impl : ty_impl_group.second ) - { - this->visit_type_impl(ty_impl); - } - } - for( auto& ty_impl : crate.m_primitive_type_impls ) - { - this->visit_type_impl(ty_impl); - } - for( auto& ty_impl : crate.m_generic_type_impls ) - { - this->visit_type_impl(ty_impl); - } + visit_impls<::HIR::TypeImpl>(crate.m_type_impls, [&](::HIR::TypeImpl& ty_impl){ this->visit_type_impl(ty_impl); }); for( auto& impl_group : crate.m_trait_impls ) { - for( auto& impl : impl_group.second ) - { - this->visit_trait_impl(impl_group.first, impl); - } + visit_impls<::HIR::TraitImpl>(impl_group.second, [&](::HIR::TraitImpl& ty_impl){ this->visit_trait_impl(impl_group.first, ty_impl); }); } for( auto& impl_group : crate.m_marker_impls ) { - for( auto& impl : impl_group.second ) - { - this->visit_marker_impl(impl_group.first, impl); - } + visit_impls<::HIR::MarkerImpl>(impl_group.second, [&](::HIR::MarkerImpl& ty_impl){ this->visit_marker_impl(impl_group.first, ty_impl); }); } } diff --git a/src/hir_conv/resolve_ufcs_outer.cpp b/src/hir_conv/resolve_ufcs_outer.cpp index 285f6e55..1f245a0d 100644 --- a/src/hir_conv/resolve_ufcs_outer.cpp +++ b/src/hir_conv/resolve_ufcs_outer.cpp @@ -339,50 +339,46 @@ namespace { } +namespace { + template<typename T> + void sort_impl_group(::HIR::Crate::ImplGroup<T>& ig) + { + auto new_end = ::std::remove_if(ig.generic.begin(), ig.generic.end(), [&ig](T& ty_impl) { + const auto& type = ty_impl.m_type; // Using field accesses in templates feels so dirty + const ::HIR::SimplePath* path = type.get_sort_path(); + + if( path ) + { + ig.named[*path].push_back(mv$(ty_impl)); + } + else if( type.m_data.is_Path() || type.m_data.is_Generic() ) + { + return false; + } + else + { + ig.non_named.push_back(mv$(ty_impl)); + } + return true; + }); + ig.generic.erase(new_end, ig.generic.end()); + } +} + void ConvertHIR_ResolveUFCS_Outer(::HIR::Crate& crate) { Visitor exp { crate }; exp.visit_crate( crate ); // Sort impls! - auto new_end = ::std::remove_if(crate.m_generic_type_impls.begin(), crate.m_generic_type_impls.end(), [&crate](::HIR::TypeImpl& ty_impl) { - const auto& type = ty_impl.m_type; - const ::HIR::SimplePath* path = nullptr; - // - Generic paths get sorted - if( TU_TEST1(type.m_data, Path, .path.m_data.is_Generic()) ) - { - path = &type.m_data.as_Path().path.m_data.as_Generic().m_path; - } - // - So do trait objects - else if( type.m_data.is_TraitObject() ) - { - path = &type.m_data.as_TraitObject().m_trait.m_path.m_path; - } - else - { - // Keep as nullptr, will search primitive list - } - - if( path ) - { - auto it = crate.m_named_type_impls.find(*path); - if( it == crate.m_named_type_impls.end() ) - { - it = crate.m_named_type_impls.insert( ::std::make_pair(*path, ::std::vector<::HIR::TypeImpl>()) ).first; - } - it->second.push_back(mv$(ty_impl)); - } - else if( type.m_data.is_Path() || type.m_data.is_Generic() ) - { - return false; - } - else - { - crate.m_primitive_type_impls.push_back(mv$(ty_impl)); - } - return true; - }); - crate.m_generic_type_impls.erase(new_end, crate.m_generic_type_impls.end()); - - DEBUG("Impl counts: " << crate.m_named_type_impls.size() << " path groups, " << crate.m_primitive_type_impls.size() << " primitive, " << crate.m_generic_type_impls.size() << " ungrouped"); + sort_impl_group(crate.m_type_impls); + DEBUG("Type impl counts: " << crate.m_type_impls.named.size() << " path groups, " << crate.m_type_impls.non_named.size() << " primitive, " << crate.m_type_impls.generic.size() << " ungrouped"); + for(auto& impl_group : crate.m_trait_impls) + { + sort_impl_group(impl_group.second); + } + for(auto& impl_group : crate.m_marker_impls) + { + sort_impl_group(impl_group.second); + } } diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index b4ab564c..f09917de 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -50,16 +50,18 @@ namespace { { for(auto& impl : new_trait_impls) { + ::std::vector<::HIR::TraitImpl>* trait_impl_list; switch(impl.first) { case ::HIR::ExprNode_Closure::Class::Once: - crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_once")].push_back( mv$(impl.second) ); - break; + trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_once")].get_list_for_type_mut(impl.second.m_type); + if(0) case ::HIR::ExprNode_Closure::Class::Mut: - crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_mut" )].push_back( mv$(impl.second) ); - break; + trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn_mut" )].get_list_for_type_mut(impl.second.m_type); + if(0) case ::HIR::ExprNode_Closure::Class::Shared: - crate.m_trait_impls[crate.get_lang_item_path(sp, "fn" )].push_back( mv$(impl.second) ); + trait_impl_list = &crate.m_trait_impls[crate.get_lang_item_path(sp, "fn" )].get_list_for_type_mut(impl.second.m_type); + trait_impl_list->push_back( mv$(impl.second) ); break; case ::HIR::ExprNode_Closure::Class::NoCapture: { assert(impl.second.m_methods.size() == 1); @@ -68,7 +70,7 @@ namespace { // NOTE: This should always have a name const auto& path = impl.second.m_type.m_data.as_Path().path.m_data.as_Generic().m_path; DEBUG("Adding type impl " << path); - auto list_it = crate.m_named_type_impls.insert( ::std::make_pair(path, ::std::vector<::HIR::TypeImpl>()) ).first; + auto list_it = crate.m_type_impls.named.insert( ::std::make_pair(path, ::std::vector<::HIR::TypeImpl>()) ).first; list_it->second.push_back( ::HIR::TypeImpl { mv$(impl.second.m_params), mv$(impl.second.m_type), diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index ced322a4..f7f85b23 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -202,7 +202,7 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) impl.m_methods.insert(::std::make_pair( RcString::new_interned("clone"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::std::move(fcn) } )); // Add impl to the crate - state.crate.m_trait_impls[state.lang_Clone].push_back( ::std::move(impl) ); + state.crate.m_trait_impls[state.lang_Clone].get_list_for_type_mut(impl.m_type).push_back( ::std::move(impl) ); } void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) @@ -237,7 +237,9 @@ void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list) //DEBUG("add_function(" << p << ")"); auto e = trans_list.add_function(::std::move(p)); - auto it = ::std::find_if( impl_list_it->second.begin(), impl_list_it->second.end(), [&](const auto& i){ return i.m_type == ty; }); + const auto* impl_list = impl_list_it->second.get_list_for_type(ty); + assert(impl_list); + auto it = ::std::find_if( impl_list->begin(), impl_list->end(), [&](const auto& i){ return i.m_type == ty; }); assert( it->m_methods.size() == 1 ); e->ptr = &it->m_methods.begin()->second.data; } diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 7ef605b9..91b00084 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -165,6 +165,78 @@ namespace { } } } + + void Trans_Enumerate_Public_TraitImpl(EnumState& state, StaticTraitResolve& resolve, const ::HIR::SimplePath& trait_path, /*const*/ ::HIR::TraitImpl& impl) + { + static Span sp; + const auto& impl_ty = impl.m_type; + TRACE_FUNCTION_F("Impl " << trait_path << impl.m_trait_args << " for " << impl_ty); + if( impl.m_params.m_types.size() == 0 ) + { + auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.m_trait_args, nullptr); + + // Emit each method/static (in the trait itself) + const auto& trait = resolve.m_crate.get_trait_by_path(sp, trait_path); + for(const auto& vi : trait.m_values) + { + TRACE_FUNCTION_F("Item " << vi.first << " : " << vi.second.tag_str()); + // Constant, no codegen + if( vi.second.is_Constant() ) + ; + // Generic method, no codegen + else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) + ; + // VTable, magic + else if( vi.first == "vtable#" ) + ; + else + { + // Check bounds before queueing for codegen + if( vi.second.is_Function() ) + { + bool rv = true; + for(const auto& b : vi.second.as_Function().m_params.m_bounds) + { + if( !b.is_TraitBound() ) continue; + const auto& be = b.as_TraitBound(); + + auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); + auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); + for(auto& ty : b_tp_mono.m_path.m_params.m_types) { + resolve.expand_associated_types(sp, ty); + } + for(auto& assoc_bound : b_tp_mono.m_type_bounds) { + resolve.expand_associated_types(sp, assoc_bound.second); + } + + rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { + return true; + }); + if( !rv ) + break; + } + if( !rv ) + continue ; + } + auto path = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(trait_path, impl.m_trait_args.clone()), vi.first); + Trans_Enumerate_FillFrom_PathMono(state, mv$(path)); + //state.enum_fcn(mv$(path), fcn.second.data, {}); + } + } + for(auto& m : impl.m_methods) + { + if( m.second.data.m_params.m_types.size() > 0 ) + m.second.data.m_save_code = true; + } + } + else + { + for(auto& m : impl.m_methods) + { + m.second.data.m_save_code = true; + } + } + } } /// Enumerate trans items for all public non-generic items (library crate) @@ -180,76 +252,21 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) for(auto& impl_group : crate.m_trait_impls) { const auto& trait_path = impl_group.first; - for(auto& impl : impl_group.second) + for(auto& impl_list : impl_group.second.named) { - const auto& impl_ty = impl.m_type; - TRACE_FUNCTION_F("Impl " << trait_path << impl.m_trait_args << " for " << impl_ty); - if( impl.m_params.m_types.size() == 0 ) + for(auto& impl : impl_list.second) { - auto cb_monomorph = monomorphise_type_get_cb(sp, &impl_ty, &impl.m_trait_args, nullptr); - - // Emit each method/static (in the trait itself) - const auto& trait = crate.get_trait_by_path(sp, trait_path); - for(const auto& vi : trait.m_values) - { - TRACE_FUNCTION_F("Item " << vi.first << " : " << vi.second.tag_str()); - // Constant, no codegen - if( vi.second.is_Constant() ) - ; - // Generic method, no codegen - else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) - ; - // VTable, magic - else if( vi.first == "vtable#" ) - ; - else - { - // Check bounds before queueing for codegen - if( vi.second.is_Function() ) - { - bool rv = true; - for(const auto& b : vi.second.as_Function().m_params.m_bounds) - { - if( !b.is_TraitBound() ) continue; - const auto& be = b.as_TraitBound(); - - auto b_ty_mono = monomorphise_type_with(sp, be.type, cb_monomorph); resolve.expand_associated_types(sp, b_ty_mono); - auto b_tp_mono = monomorphise_traitpath_with(sp, be.trait, cb_monomorph, false); - for(auto& ty : b_tp_mono.m_path.m_params.m_types) { - resolve.expand_associated_types(sp, ty); - } - for(auto& assoc_bound : b_tp_mono.m_type_bounds) { - resolve.expand_associated_types(sp, assoc_bound.second); - } - - rv = resolve.find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [&](const auto& impl, bool) { - return true; - }); - if( !rv ) - break; - } - if( !rv ) - continue ; - } - auto path = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(trait_path, impl.m_trait_args.clone()), vi.first); - Trans_Enumerate_FillFrom_PathMono(state, mv$(path)); - //state.enum_fcn(mv$(path), fcn.second.data, {}); - } - } - for(auto& m : impl.m_methods) - { - if( m.second.data.m_params.m_types.size() > 0 ) - m.second.data.m_save_code = true; - } - } - else - { - for(auto& m : impl.m_methods) - { - m.second.data.m_save_code = true; - } + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); } } + for(auto& impl : impl_group.second.non_named) + { + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + } + for(auto& impl : impl_group.second.generic) + { + Trans_Enumerate_Public_TraitImpl(state, resolve, trait_path, impl); + } } struct H1 { @@ -281,18 +298,18 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) } } }; - for(auto& impl_grp : crate.m_named_type_impls) + for(auto& impl_grp : crate.m_type_impls.named) { for(auto& impl : impl_grp.second) { H1::enumerate_type_impl(state, impl); } } - for(auto& impl : crate.m_primitive_type_impls) + for(auto& impl : crate.m_type_impls.non_named) { H1::enumerate_type_impl(state, impl); } - for(auto& impl : crate.m_generic_type_impls) + for(auto& impl : crate.m_type_impls.generic) { H1::enumerate_type_impl(state, impl); } |