summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-06-09 20:31:41 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-06-09 20:31:41 +0800
commita9f501bde9d8ff5e714d0ef2663177b0949f95cc (patch)
tree47189972d96bb44e2111e707987aabf75f9e3872
parent8992eaa470e27ed3da396aed41ce741bc509bb0f (diff)
downloadmrust-a9f501bde9d8ff5e714d0ef2663177b0949f95cc.tar.gz
HIR - Sort trait impls too
-rw-r--r--src/hir/deserialise.cpp17
-rw-r--r--src/hir/from_ast.cpp10
-rw-r--r--src/hir/hir.hpp39
-rw-r--r--src/hir/hir_ops.cpp145
-rw-r--r--src/hir/serialise.cpp13
-rw-r--r--src/hir/type.hpp18
-rw-r--r--src/hir/visitor.cpp47
-rw-r--r--src/hir_conv/resolve_ufcs_outer.cpp76
-rw-r--r--src/hir_expand/closures.cpp14
-rw-r--r--src/trans/auto_impls.cpp6
-rw-r--r--src/trans/enumerate.cpp155
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);
}