summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp10
-rw-r--r--src/hir/hir.hpp11
-rw-r--r--src/hir/serialise.cpp2
-rw-r--r--src/hir_expand/vtable.cpp27
-rw-r--r--src/hir_typeck/common.cpp3
-rw-r--r--src/mir/from_hir.cpp5
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({