summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/deserialise.cpp8
-rw-r--r--src/hir/from_ast.cpp1
-rw-r--r--src/hir/hir.hpp2
-rw-r--r--src/hir/serialise.cpp7
-rw-r--r--src/hir/visitor.cpp4
-rw-r--r--src/hir_expand/closures.cpp3
-rw-r--r--src/hir_expand/vtable.cpp39
-rw-r--r--src/trans/enumerate.cpp24
8 files changed, 77 insertions, 11 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index e3009cfc..45876d88 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -160,6 +160,14 @@ namespace {
m_in.read_bool(), deserialise_constant()
} ) );
}
+ size_t static_count = m_in.read_count();
+ for(size_t i = 0; i < static_count; i ++)
+ {
+ auto name = m_in.read_string();
+ rv.m_statics.insert( ::std::make_pair( mv$(name), ::HIR::TraitImpl::ImplEnt< ::HIR::Static> {
+ m_in.read_bool(), deserialise_static()
+ } ) );
+ }
size_t type_count = m_in.read_count();
for(size_t i = 0; i < type_count; i ++)
{
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 5a758354..50060ccd 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -1318,6 +1318,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
mv$(methods),
mv$(constants),
+ {}, // Statics
mv$(types),
LowerHIR_SimplePath(Span(), ast_mod.path())
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index 0fc12a55..20cac608 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -339,6 +339,8 @@ public:
::std::map< ::std::string, ImplEnt< ::HIR::Function> > m_methods;
::std::map< ::std::string, ImplEnt< ::HIR::Constant> > m_constants;
+ ::std::map< ::std::string, ImplEnt< ::HIR::Static> > m_statics;
+
::std::map< ::std::string, ImplEnt< ::HIR::TypeRef> > m_types;
::HIR::SimplePath m_src_module;
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index 30ce1bd4..33f8123f 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -297,6 +297,13 @@ namespace {
m_out.write_bool(v.second.is_specialisable);
serialise(v.second.data);
}
+ m_out.write_count(impl.m_statics.size());
+ for(const auto& v : impl.m_statics) {
+ DEBUG("static " << v.first);
+ m_out.write_string(v.first);
+ m_out.write_bool(v.second.is_specialisable);
+ serialise(v.second.data);
+ }
m_out.write_count(impl.m_types.size());
for(const auto& v : impl.m_types) {
DEBUG("type " << v.first);
diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp
index faa75e0a..889b3a77 100644
--- a/src/hir/visitor.cpp
+++ b/src/hir/visitor.cpp
@@ -133,6 +133,10 @@ void ::HIR::Visitor::visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR
DEBUG("const " << ent.first);
this->visit_constant(p + ent.first, ent.second.data);
}
+ for(auto& ent : impl.m_statics) {
+ DEBUG("static " << ent.first);
+ this->visit_static(p + ent.first, ent.second.data);
+ }
for(auto& ent : impl.m_types) {
DEBUG("type " << ent.first);
this->visit_type(ent.second.data);
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index f1b280ed..4ffc88ac 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -309,6 +309,7 @@ namespace {
} }
),
{},
+ {},
make_map1(
::std::string("Output"), ::HIR::TraitImpl::ImplEnt< ::HIR::TypeRef> { false, mv$(ret_ty) }
),
@@ -346,6 +347,7 @@ namespace {
),
{},
{},
+ {},
::HIR::SimplePath()
};
}
@@ -380,6 +382,7 @@ namespace {
),
{},
{},
+ {},
::HIR::SimplePath()
};
}
diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp
index 332ad7e5..e92fef92 100644
--- a/src/hir_expand/vtable.cpp
+++ b/src/hir_expand/vtable.cpp
@@ -15,12 +15,13 @@ namespace {
class OuterVisitor:
public ::HIR::Visitor
{
+ const ::HIR::Crate& m_crate;
//StaticTraitResolve m_resolve;
::std::function<::HIR::SimplePath(bool, ::std::string, ::HIR::Struct)> m_new_type;
::HIR::SimplePath m_lang_Sized;
public:
- OuterVisitor(const ::HIR::Crate& crate)//:
- //m_resolve(crate)
+ OuterVisitor(const ::HIR::Crate& crate):
+ m_crate(crate)
{
m_lang_Sized = crate.get_lang_item_path_opt("sized");
}
@@ -125,6 +126,8 @@ namespace {
}
if( ve.m_params.m_types.size() > 0 ) {
DEBUG("- '" << vi.first << "' NOT object safe (generic), not creating vtable");
+ tr.m_value_indexes.clear();
+ tr.m_type_indexes.clear();
return ;
}
@@ -194,10 +197,42 @@ namespace {
void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
{
+ static Span sp;
TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type);
//auto _ = this->m_resolve.set_impl_generics(impl.m_params);
::HIR::Visitor::visit_trait_impl(trait_path, impl);
+
+ // Check if the trait has a vtable, and if it does emit an associated static for it.
+ const auto& tr = m_crate.get_trait_by_path(sp, trait_path);
+ if(tr.m_value_indexes.size() > 0)
+ {
+ auto trait_gpath = ::HIR::GenericPath(trait_path, impl.m_trait_args.clone());
+
+ ::std::vector< ::HIR::Literal> vals;
+ vals.resize( tr.m_value_indexes.size() );
+ for(const auto& m : tr.m_value_indexes)
+ {
+ //ASSERT_BUG(sp, tr.m_values.at(m.first).is_Function(), "TODO: Handle generating vtables with non-function items");
+ vals.at(m.second) = ::HIR::Literal::make_BorrowOf( ::HIR::Path(impl.m_type.clone(), trait_gpath.clone(), m.first) );
+ }
+
+ auto vtable_sp = trait_path;
+ vtable_sp.m_components.back() += "#vtable";
+ auto vtable_params = impl.m_trait_args.clone();
+ for(const auto& ty : tr.m_type_indexes) {
+ ::HIR::Path path( impl.m_type.clone(), mv$(trait_gpath), ty.first );
+ vtable_params.m_types.push_back( ::HIR::TypeRef( mv$(path) ) );
+ }
+
+ const auto& vtable_ref = m_crate.get_struct_by_path(sp, vtable_sp);
+ impl.m_statics.insert(::std::make_pair( "#vtable", ::HIR::TraitImpl::ImplEnt<::HIR::Static> { true, ::HIR::Static {
+ false,
+ ::HIR::TypeRef::new_path(::HIR::GenericPath(mv$(vtable_sp), mv$(vtable_params)), &vtable_ref),
+ {},
+ ::HIR::Literal::make_List( mv$(vals) )
+ } } ));
+ }
}
};
}
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 60bfc037..a18b91b1 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -182,9 +182,9 @@ namespace {
const auto& trait_vi = trait_vi_it->second;
- if( e.item == "#vtable" ) {
- return EntPtr::make_VTable({});
- }
+ //if( e.item == "#vtable" ) {
+ // return EntPtr::make_VTable({});
+ //}
bool is_dynamic = false;
::std::vector<::HIR::TypeRef> best_impl_params;
@@ -208,12 +208,12 @@ namespace {
TU_MATCHA( (trait_vi), (ve),
(Constant, ),
(Static,
- //auto it = impl.m_statics.find(e.item);
- //if( it == impl.m_statics.end() ) {
- // DEBUG("Static " << e.item << " missing in trait " << e.trait << " for " << *e.type);
- // return false;
- //}
- //is_spec = it->second.is_specialisable;
+ auto it = impl.m_statics.find(e.item);
+ if( it == impl.m_statics.end() ) {
+ DEBUG("Static " << e.item << " missing in trait " << e.trait << " for " << *e.type);
+ return false;
+ }
+ is_spec = it->second.is_specialisable;
),
(Function,
auto fit = impl.m_methods.find(e.item);
@@ -249,6 +249,12 @@ namespace {
TU_MATCHA( (trait_vi), (ve),
(Constant, TODO(sp, "Associated constant"); ),
(Static,
+ auto it = impl.m_statics.find(e.item);
+ if( it != impl.m_statics.end() )
+ {
+ DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
+ return EntPtr { &it->second.data };
+ }
TODO(sp, "Associated static - " << path);
),
(Function,