diff options
-rw-r--r-- | src/hir/deserialise.cpp | 8 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 1 | ||||
-rw-r--r-- | src/hir/hir.hpp | 2 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 7 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 4 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 3 | ||||
-rw-r--r-- | src/hir_expand/vtable.cpp | 39 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 24 |
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, |