diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/deserialise.cpp | 10 | ||||
-rw-r--r-- | src/hir/hir.hpp | 11 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 2 | ||||
-rw-r--r-- | src/hir_expand/vtable.cpp | 27 | ||||
-rw-r--r-- | src/hir_typeck/common.cpp | 3 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 5 |
6 files changed, 31 insertions, 27 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 3d84c9d6..2d16b230 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -539,12 +539,9 @@ namespace { ::HIR::TraitValueItem deserialise_traitvalueitem() { - auto tag = m_in.read_tag(); - auto idx = m_in.read_count(); - ::HIR::TraitValueItem rv; - switch( tag ) + switch( m_in.read_tag() ) { - #define _(x, ...) case ::HIR::TraitValueItem::TAG_##x: DEBUG("- " #x); rv = ::HIR::TraitValueItem::make_##x( __VA_ARGS__ ); break; + #define _(x, ...) case ::HIR::TraitValueItem::TAG_##x: DEBUG("- " #x); return ::HIR::TraitValueItem::make_##x( __VA_ARGS__ ); break; _(Constant, deserialise_constant() ) _(Static, deserialise_static() ) _(Function, deserialise_function() ) @@ -553,8 +550,6 @@ namespace { DEBUG("Invalid TraitValueItem tag"); throw ""; } - rv.vtable_ofs = idx; - return rv; } ::HIR::AssociatedType deserialise_associatedtype() { @@ -866,6 +861,7 @@ namespace { rv.m_is_marker = m_in.read_bool(); rv.m_types = deserialise_strumap< ::HIR::AssociatedType>(); rv.m_values = deserialise_strumap< ::HIR::TraitValueItem>(); + rv.m_value_indexes = deserialise_strumap< unsigned int>(); rv.m_type_indexes = deserialise_strumap< unsigned int>(); return rv; } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 1a933993..0fc12a55 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -231,15 +231,10 @@ struct AssociatedType ::std::vector< ::HIR::TraitPath> m_trait_bounds; ::HIR::TypeRef m_default; }; -TAGGED_UNION_EX(TraitValueItem, (), Constant, ( +TAGGED_UNION(TraitValueItem, Constant, (Constant, Constant), (Static, Static), (Function, Function) - ), - (),(), - ( - unsigned int vtable_ofs = ~0u; - ) ); struct Trait { @@ -252,7 +247,9 @@ struct Trait ::std::unordered_map< ::std::string, AssociatedType > m_types; ::std::unordered_map< ::std::string, TraitValueItem > m_values; - // Indexes in the parameter list for each associated type + // Indexes into the vtable for each present method and value + ::std::unordered_map< ::std::string, unsigned int > m_value_indexes; + // Indexes in the vtable parameter list for each associated type ::std::unordered_map< ::std::string, unsigned int > m_type_indexes; Trait( GenericParams gps, ::std::string lifetime, ::std::vector< ::HIR::TraitPath> parents): diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index c58780a0..d890aed6 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -817,12 +817,12 @@ namespace { m_out.write_bool( item.m_is_marker ); serialise_strmap( item.m_types ); serialise_strmap( item.m_values ); + serialise_strmap( item.m_value_indexes ); serialise_strmap( item.m_type_indexes ); } void serialise(const ::HIR::TraitValueItem& tvi) { m_out.write_tag( tvi.tag() ); - m_out.write_count( tvi.vtable_ofs ); TU_MATCHA( (tvi), (e), (Constant, DEBUG("Constant"); diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp index 5b4a8c39..332ad7e5 100644 --- a/src/hir_expand/vtable.cpp +++ b/src/hir_expand/vtable.cpp @@ -61,10 +61,17 @@ namespace { ::std::unordered_map< ::std::string,unsigned int> assoc_type_indexes; struct Foo { ::HIR::Trait* trait_ptr; + ::HIR::GenericParams params; unsigned int i; void add_types_from_trait(const ::HIR::Trait& tr) { for(const auto& ty : tr.m_types) { - trait_ptr->m_type_indexes[ty.first] = i; + auto rv = trait_ptr->m_type_indexes.insert( ::std::make_pair(ty.first, i) ); + if(rv.second == false) { + //TODO(Span(), "Handle conflicting associated types - '" << ty.first << "'"); + } + else { + params.m_types.push_back( ::HIR::TypeParamDef { "a#"+ty.first, {}, ty.second.is_sized } ); + } i ++; } // TODO: Iterate supertraits too. @@ -73,7 +80,12 @@ namespace { } } }; - Foo { &tr, static_cast<unsigned int>(tr.m_params.m_types.size()) }.add_types_from_trait(tr); + Foo visitor { &tr, {}, static_cast<unsigned int>(tr.m_params.m_types.size()) }; + for(const auto& tp : tr.m_params.m_types) { + visitor.params.m_types.push_back( ::HIR::TypeParamDef { tp.m_name, {}, tp.m_is_sized } ); + } + visitor.add_types_from_trait(tr); + auto args = mv$(visitor.params); auto clone_cb = [&](const auto& t, auto& o) { if(t.m_data.is_Path() && t.m_data.as_Path().path.m_data.is_UfcsKnown()) { @@ -131,10 +143,13 @@ namespace { if( visit_ty_with(fcn_type, [&](const auto& t){ return (t == ::HIR::TypeRef("Self", 0xFFFF)); }) ) { DEBUG("- '" << vi.first << "' NOT object safe (Self), not creating vtable - " << fcn_type); + tr.m_value_indexes.clear(); + tr.m_type_indexes.clear(); return ; } - vi.second.vtable_ofs = fields.size(); + tr.m_value_indexes[vi.first] = fields.size(); + DEBUG("- '" << vi.first << "' is @" << fields.size()); fields.push_back( ::std::make_pair( vi.first, ::HIR::VisEnt< ::HIR::TypeRef> { true, mv$(fcn_type) } @@ -150,19 +165,15 @@ namespace { } ::HIR::PathParams params; - ::HIR::GenericParams args; { unsigned int i = 0; for(const auto& tp : tr.m_params.m_types) { - args.m_types.push_back( ::HIR::TypeParamDef { tp.m_name, {}, tp.m_is_sized } ); params.m_types.push_back( ::HIR::TypeRef(tp.m_name, i) ); i ++; } - for(const auto& ty : tr.m_types) { - args.m_types.push_back( ::HIR::TypeParamDef { "a#"+ty.first, {}, ty.second.is_sized } ); + for(const auto& ty : tr.m_type_indexes) { ::HIR::Path path( ::HIR::TypeRef("Self",0xFFFF), trait_path.clone(), ty.first ); params.m_types.push_back( ::HIR::TypeRef( mv$(path) ) ); - i ++; } } // TODO: Would like to have access to the publicity marker diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp index ca6f6fe4..bed6b0f4 100644 --- a/src/hir_typeck/common.cpp +++ b/src/hir_typeck/common.cpp @@ -350,7 +350,8 @@ namespace { ::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl) { DEBUG("tpl = " << tpl); - ASSERT_BUG(sp, params.m_types.size() == params_def.m_types.size(), "Parameter count mismatch - exp " << params_def.m_types.size() << ", got " << params.m_types.size()); + ASSERT_BUG(sp, params.m_types.size() == params_def.m_types.size(), + "Parameter count mismatch - exp " << params_def.m_types.size() << ", got " << params.m_types.size() << " for " << params << " and " << params_def.fmt_args()); return monomorphise_type_with(sp, tpl, [&](const auto& gt)->const auto& { const auto& e = gt.m_data.as_Generic(); if( e.binding == 0xFFFF ) { diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 7ded3cb4..a763b42c 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1376,10 +1376,9 @@ namespace { const auto& trait = *te.m_trait.m_trait_ptr; // 1. Get the vtable index for this function - unsigned int vtable_idx = trait.m_values.at( pe.item ).vtable_ofs; - if( vtable_idx == ~0u ) { + if( trait.m_value_indexes.count(pe.item) == 0 ) BUG(sp, "Calling method '" << pe.item << "' of " << pe.trait << " which isn't in the vtable"); - } + unsigned int vtable_idx = trait.m_value_indexes.at( pe.item ); // 2. Load from the vtable auto vtable_rval = ::MIR::RValue::make_DstMeta({ |