summaryrefslogtreecommitdiff
path: root/src/trans/enumerate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/trans/enumerate.cpp')
-rw-r--r--src/trans/enumerate.cpp953
1 files changed, 523 insertions, 430 deletions
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 4e04ddf9..d8426022 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -11,6 +11,7 @@
#include "trans_list.hpp"
#include <hir/hir.hpp>
#include <mir/mir.hpp>
+#include <mir/helpers.hpp>
#include <hir_typeck/common.hpp> // monomorph
#include <hir_typeck/static.hpp> // StaticTraitResolve
#include <hir/item_path.hpp>
@@ -47,11 +48,12 @@ namespace {
TransList Trans_Enumerate_CommonPost(EnumState& state);
void Trans_Enumerate_Types(EnumState& state);
void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, const Trans_Params& pp);
+void Trans_Enumerate_FillFrom_PathMono(EnumState& state, ::HIR::Path path);
void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Function& function, const Trans_Params& pp);
void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Static& stat, TransList_Static& stat_out, Trans_Params pp={});
void Trans_Enumerate_FillFrom_VTable (EnumState& state, ::HIR::Path vtable_path, const Trans_Params& pp);
void Trans_Enumerate_FillFrom_Literal(EnumState& state, const ::HIR::Literal& lit, const Trans_Params& pp);
-void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code, const Trans_Params& pp);
+void Trans_Enumerate_FillFrom_MIR(MIR::EnumCache& state, const ::MIR::Function& code);
/// Enumerate trans items starting from `::main` (binary crate)
TransList Trans_Enumerate_Main(const ::HIR::Crate& crate)
@@ -63,21 +65,25 @@ TransList Trans_Enumerate_Main(const ::HIR::Crate& crate)
auto c_start_path = crate.get_lang_item_path_opt("mrustc-start");
if( c_start_path == ::HIR::SimplePath() )
{
+ // user entrypoint
+ auto main_path = crate.get_lang_item_path(Span(), "mrustc-main");
+ const auto& main_fcn = crate.get_function_by_path(sp, main_path);
+
+ state.enum_fcn( main_path, main_fcn, {} );
+
// "start" language item
// - Takes main, and argc/argv as arguments
{
auto start_path = crate.get_lang_item_path(sp, "start");
const auto& fcn = crate.get_function_by_path(sp, start_path);
- state.enum_fcn( start_path, fcn, {} );
- }
-
- // user entrypoint
- {
- auto main_path = crate.get_lang_item_path(Span(), "mrustc-main");
- const auto& fcn = crate.get_function_by_path(sp, main_path);
-
- state.enum_fcn( main_path, fcn, {} );
+ Trans_Params lang_start_pp;
+ if( TARGETVER_1_29 )
+ {
+ // With 1.29, this now takes main's return type as a type parameter
+ lang_start_pp.pp_method.m_types.push_back( main_fcn.m_return.clone() );
+ }
+ state.enum_fcn( start_path, fcn, mv$(lang_start_pp) );
}
}
else
@@ -148,39 +154,29 @@ namespace {
const bool EMIT_ALL = true;
for(auto& vi : mod.m_value_items)
{
- Trans_Enumerate_ValItem(state, vi.second->ent, EMIT_ALL || (is_visible && vi.second->is_public), [&](){ return mod_path + vi.first; });
+ Trans_Enumerate_ValItem(state, vi.second->ent, EMIT_ALL || (is_visible && vi.second->publicity.is_global()), [&](){ return mod_path + vi.first; });
}
for(auto& ti : mod.m_mod_items)
{
if(auto* e = ti.second->ent.opt_Module() )
{
- Trans_Enumerate_Public_Mod(state, *e, mod_path + ti.first, ti.second->is_public);
+ Trans_Enumerate_Public_Mod(state, *e, mod_path + ti.first, ti.second->publicity.is_global());
}
}
}
-}
-
-/// Enumerate trans items for all public non-generic items (library crate)
-TransList Trans_Enumerate_Public(::HIR::Crate& crate)
-{
- static Span sp;
- EnumState state { crate };
- Trans_Enumerate_Public_Mod(state, crate.m_root_module, ::HIR::SimplePath(crate.m_crate_name,{}), true);
-
- // Impl blocks
- StaticTraitResolve resolve { crate };
- for(auto& impl : crate.m_trait_impls)
+ void Trans_Enumerate_Public_TraitImpl(EnumState& state, StaticTraitResolve& resolve, const ::HIR::SimplePath& trait_path, /*const*/ ::HIR::TraitImpl& impl)
{
- const auto& impl_ty = impl.second.m_type;
- TRACE_FUNCTION_F("Impl " << impl.first << impl.second.m_trait_args << " for " << impl_ty);
- if( impl.second.m_params.m_types.size() == 0 )
+ 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.second.m_trait_args, nullptr);
+ 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, impl.first);
+ 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());
@@ -222,11 +218,12 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate)
if( !rv )
continue ;
}
- auto p = ::HIR::Path(impl_ty.clone(), ::HIR::GenericPath(impl.first, impl.second.m_trait_args.clone()), vi.first);
- Trans_Enumerate_FillFrom_Path(state, p, {});
+ 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.second.m_methods)
+ for(auto& m : impl.m_methods)
{
if( m.second.data.m_params.m_types.size() > 0 )
m.second.data.m_save_code = true;
@@ -234,37 +231,88 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate)
}
else
{
- for(auto& m : impl.second.m_methods)
+ for(auto& m : impl.m_methods)
{
m.second.data.m_save_code = true;
}
}
}
- for(auto& impl : crate.m_type_impls)
+}
+
+/// Enumerate trans items for all public non-generic items (library crate)
+TransList Trans_Enumerate_Public(::HIR::Crate& crate)
+{
+ static Span sp;
+ EnumState state { crate };
+
+ Trans_Enumerate_Public_Mod(state, crate.m_root_module, ::HIR::SimplePath(crate.m_crate_name,{}), true);
+
+ // Impl blocks
+ StaticTraitResolve resolve { crate };
+ for(auto& impl_group : crate.m_trait_impls)
{
- if( impl.m_params.m_types.size() == 0 )
+ const auto& trait_path = impl_group.first;
+ for(auto& impl_list : impl_group.second.named)
{
- for(auto& fcn : impl.m_methods)
+ for(auto& impl : impl_list.second)
{
- if( fcn.second.data.m_params.m_types.size() == 0 )
+ 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
+ {
+ static void enumerate_type_impl(EnumState& state, ::HIR::TypeImpl& impl)
+ {
+ TRACE_FUNCTION_F("impl" << impl.m_params.fmt_args() << " " << impl.m_type);
+ if( impl.m_params.m_types.size() == 0 )
+ {
+ for(auto& fcn : impl.m_methods)
{
- auto p = ::HIR::Path(impl.m_type.clone(), fcn.first);
- Trans_Enumerate_FillFrom_Path(state, p, {});
+ DEBUG("fn " << fcn.first << fcn.second.data.m_params.fmt_args());
+ if( fcn.second.data.m_params.m_types.size() == 0 )
+ {
+ auto path = ::HIR::Path(impl.m_type.clone(), fcn.first);
+ state.enum_fcn(mv$(path), fcn.second.data, {});
+ }
+ else
+ {
+ fcn.second.data.m_save_code = true;
+ }
}
- else
+ }
+ else
+ {
+ for(auto& m : impl.m_methods)
{
- fcn.second.data.m_save_code = true;
+ m.second.data.m_save_code = true;
}
}
}
- else
+ };
+ for(auto& impl_grp : crate.m_type_impls.named)
+ {
+ for(auto& impl : impl_grp.second)
{
- for(auto& m : impl.m_methods)
- {
- m.second.data.m_save_code = true;
- }
+ H1::enumerate_type_impl(state, *impl);
}
}
+ for(auto& impl : crate.m_type_impls.non_named)
+ {
+ H1::enumerate_type_impl(state, *impl);
+ }
+ for(auto& impl : crate.m_type_impls.generic)
+ {
+ H1::enumerate_type_impl(state, *impl);
+ }
auto rv = Trans_Enumerate_CommonPost(state);
@@ -332,6 +380,7 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate)
return rv;
}
+#if 0
void Trans_Enumerate_Cleanup(const ::HIR::Crate& crate, TransList& list)
{
EnumState state { crate };
@@ -377,6 +426,7 @@ void Trans_Enumerate_Cleanup(const ::HIR::Crate& crate, TransList& list)
ASSERT_BUG(Span(), it != list.m_functions.end(), "Enumerate Error - New function appeared after monomorphisation - " << e.first);
}
}
+#endif
/// Common post-processing
void Trans_Enumerate_CommonPost_Run(EnumState& state)
@@ -400,7 +450,8 @@ TransList Trans_Enumerate_CommonPost(EnumState& state)
return mv$(state.rv);
}
-namespace {
+namespace
+{
struct PtrComp
{
template<typename T>
@@ -413,7 +464,8 @@ namespace {
::StaticTraitResolve m_resolve;
::std::vector< ::std::pair< ::HIR::TypeRef, bool> >& out_list;
- ::std::map< ::HIR::TypeRef, bool > visited;
+ // TODO: Have a list of indexes into `out_list`, sorted by typeref ordering
+ ::std::vector<size_t> visited_map;
::std::set< const ::HIR::TypeRef*, PtrComp> active_set;
TypeVisitor(const ::HIR::Crate& crate, ::std::vector< ::std::pair< ::HIR::TypeRef, bool > >& out_list):
@@ -422,6 +474,11 @@ namespace {
out_list(out_list)
{}
+ ~TypeVisitor()
+ {
+ DEBUG("Visited a total of " << visited_map.size());
+ }
+
void visit_struct(const ::HIR::GenericPath& path, const ::HIR::Struct& item) {
static Span sp;
::HIR::TypeRef tmp;
@@ -499,16 +556,16 @@ namespace {
{
// If the type has already been visited, AND either this is a shallow visit, or the previous wasn't
{
- auto it = visited.find(ty);
- if( it != visited.end() )
+ auto idx_it = ::std::lower_bound(visited_map.begin(), visited_map.end(), ty, [&](size_t i, const ::HIR::TypeRef& t){ return out_list[i].first < t; });
+ if( idx_it != visited_map.end() && out_list[*idx_it].first == ty)
{
+ auto it = &out_list[*idx_it];
if( it->second == false || mode == Mode::Shallow )
{
// Return early
return ;
}
DEBUG("-- " << ty << " already visited as shallow");
- it->second = false;
}
}
TRACE_FUNCTION_F(ty << " - " << (mode == Mode::Shallow ? "Shallow" : (mode == Mode::Normal ? "Normal" : "Deep")));
@@ -566,6 +623,9 @@ namespace {
(Opaque,
BUG(Span(), "Opaque type hit in enumeration - " << ty);
),
+ (ExternType,
+ // No innards to visit
+ ),
(Struct,
visit_struct(te.path.m_data.as_Generic(), *tpb);
),
@@ -583,8 +643,7 @@ namespace {
const auto& trait = *te.m_trait.m_trait_ptr;
ASSERT_BUG(Span(), ! te.m_trait.m_path.m_path.m_components.empty(), "TODO: Data trait is empty, what can be done?");
- auto vtable_ty_spath = te.m_trait.m_path.m_path;
- vtable_ty_spath.m_components.back() += "#vtable";
+ const auto& vtable_ty_spath = trait.m_vtable_path;
const auto& vtable_ref = m_crate.get_struct_by_path(sp, vtable_ty_spath);
// Copy the param set from the trait in the trait object
::HIR::PathParams vtable_params = te.m_trait.m_path.m_params.clone();
@@ -626,36 +685,30 @@ namespace {
bool shallow = (mode == Mode::Shallow);
{
- auto rv = visited.insert( ::std::make_pair(ty.clone(), shallow) );
- if( !rv.second && ! shallow )
+ auto idx_it = ::std::lower_bound(visited_map.begin(), visited_map.end(), ty, [&](size_t i, const ::HIR::TypeRef& t){ return out_list[i].first < t; });
+ if( idx_it == visited_map.end() || out_list[*idx_it].first != ty )
{
- rv.first->second = false;
+ // Add a new entry
+ visited_map.insert(idx_it, out_list.size());
+ }
+ else
+ {
+ // Previous visit was shallow, but this one isn't
+ // - Update the entry to the to-be-pushed entry with shallow=false
+ if( !shallow && out_list[*idx_it].second )
+ {
+ *idx_it = out_list.size();
+ }
}
}
out_list.push_back( ::std::make_pair(ty.clone(), shallow) );
DEBUG("Add type " << ty << (shallow ? " (Shallow)": ""));
}
- };
-}
-
-// Enumerate types required for the enumerated items
-void Trans_Enumerate_Types(EnumState& state)
-{
- static Span sp;
- TypeVisitor tv { state.crate, state.rv.m_types };
- unsigned int types_count = 0;
- bool constructors_added;
- do
- {
- // Visit all functions that haven't been type-visited yet
- for(unsigned int i = 0; i < state.fcns_to_type_visit.size(); i++)
+ void __attribute__ ((noinline)) visit_function(const ::HIR::Path& path, const ::HIR::Function& fcn, const Trans_Params& pp)
{
- auto p = state.fcns_to_type_visit[i];
- TRACE_FUNCTION_F("Function " << ::std::find_if(state.rv.m_functions.begin(), state.rv.m_functions.end(), [&](const auto&x){ return x.second.get() == p; })->first);
- assert(p->ptr);
- const auto& fcn = *p->ptr;
- const auto& pp = p->pp;
+ Span sp;
+ auto& tv = *this;
::HIR::TypeRef tmp;
auto monomorph = [&](const auto& ty)->const auto& {
@@ -693,284 +746,170 @@ void Trans_Enumerate_Types(EnumState& state)
for(const auto& ty : mir.locals)
tv.visit_type(monomorph(ty));
- // TODO: Find all LValue::Deref instances and get the result type
+ // Find all LValue::Deref instances and get the result type
+ ::MIR::TypeResolve::args_t empty_args;
+ ::HIR::TypeRef empty_ty;
+ ::MIR::TypeResolve mir_res(sp, tv.m_resolve, FMT_CB(fcn_path), /*ret_ty=*/empty_ty, empty_args, mir);
for(const auto& block : mir.blocks)
{
- struct H {
- static const ::HIR::TypeRef& visit_lvalue(TypeVisitor& tv, const Trans_Params& pp, const ::HIR::Function& fcn, const ::MIR::LValue& lv, ::HIR::TypeRef* tmp_ty_ptr = nullptr) {
- static ::HIR::TypeRef blank;
- TRACE_FUNCTION_F(lv << (tmp_ty_ptr ? " [type]" : ""));
+ struct MirVisitor
+ //:public ::MIR::Visitor
+ {
+ TypeVisitor& tv;
+ const Trans_Params& pp;
+ const ::HIR::Function& fcn;
+ const ::MIR::TypeResolve& mir_res;
+
+ MirVisitor(TypeVisitor& tv, const Trans_Params& pp, const ::HIR::Function& fcn, const ::MIR::TypeResolve& mir_res)
+ :tv(tv)
+ ,pp(pp)
+ ,fcn(fcn)
+ ,mir_res(mir_res)
+ {
+ }
+
+ void visit_lvalue(const ::MIR::LValue& lv) //override
+ {
+ TRACE_FUNCTION_F(lv);
+ if( ::std::none_of(lv.m_wrappers.begin(), lv.m_wrappers.end(), [](const auto& w){ return w.is_Deref(); }) )
+ {
+ return ;
+ }
+ ::HIR::TypeRef tmp;
auto monomorph_outer = [&](const auto& tpl)->const auto& {
- assert(tmp_ty_ptr);
if( monomorphise_type_needed(tpl) ) {
- return *tmp_ty_ptr = pp.monomorph(tv.m_resolve, tpl);
+ return tmp = pp.monomorph(tv.m_resolve, tpl);
}
else {
return tpl;
}
};
+ const ::HIR::TypeRef* ty_p = nullptr;;
// Recurse, if Deref get the type and add it to the visitor
- TU_MATCHA( (lv), (e),
+ TU_MATCHA( (lv.m_root), (e),
(Return,
- if( tmp_ty_ptr ) {
- TODO(Span(), "Get return type for MIR type enumeration");
- }
+ MIR_TODO(mir_res, "Get return type for MIR type enumeration");
),
(Argument,
- if( tmp_ty_ptr ) {
- return monomorph_outer(fcn.m_args[e.idx].second);
- }
+ ty_p = &monomorph_outer(fcn.m_args[e].second);
),
(Local,
- if( tmp_ty_ptr ) {
- return monomorph_outer(fcn.m_code.m_mir->locals[e]);
- }
+ ty_p = &monomorph_outer(fcn.m_code.m_mir->locals[e]);
),
(Static,
- if( tmp_ty_ptr ) {
- const auto& path = e;
- TU_MATCHA( (path.m_data), (pe),
- (Generic,
- ASSERT_BUG(Span(), pe.m_params.m_types.empty(), "Path params on static - " << path);
- const auto& s = tv.m_resolve.m_crate.get_static_by_path(Span(), pe.m_path);
- return s.m_type;
- ),
- (UfcsKnown,
- TODO(Span(), "LValue::Static - UfcsKnown - " << path);
- ),
- (UfcsUnknown,
- BUG(Span(), "Encountered UfcsUnknown in LValue::Static - " << path);
- ),
- (UfcsInherent,
- TODO(Span(), "LValue::Static - UfcsInherent - " << path);
- )
- )
- }
- ),
- (Field,
- const auto& ity = visit_lvalue(tv,pp,fcn, *e.val, tmp_ty_ptr);
- if( tmp_ty_ptr )
- {
- TU_MATCH_DEF(::HIR::TypeRef::Data, (ity.m_data), (te),
- (
- BUG(Span(), "Field access of unexpected type - " << ity);
- ),
- (Tuple,
- return te[e.field_index];
- ),
- (Array,
- return *te.inner;
- ),
- (Slice,
- return *te.inner;
- ),
- (Path,
- ASSERT_BUG(Span(), te.binding.is_Struct(), "Field on non-Struct - " << ity);
- const auto& str = *te.binding.as_Struct();
- auto monomorph = [&](const auto& ty)->const auto& {
- if( monomorphise_type_needed(ty) ) {
- *tmp_ty_ptr = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, ty);
- tv.m_resolve.expand_associated_types(sp, *tmp_ty_ptr);
- return *tmp_ty_ptr;
- }
- else {
- return ty;
- }
- };
- TU_MATCHA( (str.m_data), (se),
- (Unit,
- BUG(Span(), "Field on unit-like struct - " << ity);
- ),
- (Tuple,
- ASSERT_BUG(Span(), e.field_index < se.size(), "Field index out of range in struct " << te.path);
- return monomorph(se.at(e.field_index).ent);
- ),
- (Named,
- ASSERT_BUG(Span(), e.field_index < se.size(), "Field index out of range in struct " << te.path);
- return monomorph(se.at(e.field_index).second.ent);
- )
- )
- )
- )
- }
- ),
- (Deref,
- ::HIR::TypeRef tmp;
- if( !tmp_ty_ptr ) tmp_ty_ptr = &tmp;
-
- const auto& ity = visit_lvalue(tv,pp,fcn, *e.val, tmp_ty_ptr);
- TU_MATCH_DEF(::HIR::TypeRef::Data, (ity.m_data), (te),
- (
- BUG(Span(), "Deref of unexpected type - " << ity);
+ // TODO: Monomorphise the path then hand to MIR::TypeResolve?
+ const auto& path = e;
+ TU_MATCHA( (path.m_data), (pe),
+ (Generic,
+ MIR_ASSERT(mir_res, pe.m_params.m_types.empty(), "Path params on static - " << path);
+ const auto& s = tv.m_resolve.m_crate.get_static_by_path(mir_res.sp, pe.m_path);
+ ty_p = &s.m_type;
),
- (Path,
- if( const auto* inner_ptr = tv.m_resolve.is_type_owned_box(ity) )
- {
- DEBUG("- Add type " << ity);
- tv.visit_type(*inner_ptr);
- return *inner_ptr;
- }
- else {
- BUG(Span(), "Deref on unexpected type - " << ity);
- }
+ (UfcsKnown,
+ MIR_TODO(mir_res, "LValue::Static - UfcsKnown - " << path);
),
- (Borrow,
- DEBUG("- Add type " << ity);
- tv.visit_type(*te.inner);
- return *te.inner;
+ (UfcsUnknown,
+ MIR_BUG(mir_res, "Encountered UfcsUnknown in LValue::Static - " << path);
),
- (Pointer,
- DEBUG("- Add type " << ity);
- tv.visit_type(*te.inner);
- return *te.inner;
+ (UfcsInherent,
+ MIR_TODO(mir_res, "LValue::Static - UfcsInherent - " << path);
)
)
- ),
- (Index,
- visit_lvalue(tv,pp,fcn, *e.idx, tmp_ty_ptr);
- const auto& ity = visit_lvalue(tv,pp,fcn, *e.val, tmp_ty_ptr);
- if( tmp_ty_ptr )
- {
- TU_MATCH_DEF(::HIR::TypeRef::Data, (ity.m_data), (te),
- (
- BUG(Span(), "Index of unexpected type - " << ity);
- ),
- (Array,
- return *te.inner;
- ),
- (Slice,
- return *te.inner;
- )
- )
- }
- ),
- (Downcast,
- const auto& ity = visit_lvalue(tv,pp,fcn, *e.val, tmp_ty_ptr);
- if( tmp_ty_ptr )
- {
- TU_MATCH_DEF( ::HIR::TypeRef::Data, (ity.m_data), (te),
- (
- BUG(Span(), "Downcast on unexpected type - " << ity);
- ),
- (Path,
- if( te.binding.is_Enum() )
- {
- const auto& enm = *te.binding.as_Enum();
- auto monomorph = [&](const auto& ty)->auto {
- ::HIR::TypeRef rv = monomorphise_type(pp.sp, enm.m_params, te.path.m_data.as_Generic().m_params, ty);
- tv.m_resolve.expand_associated_types(sp, rv);
- return rv;
- };
- ASSERT_BUG(Span(), enm.m_data.is_Data(), "");
- const auto& variants = enm.m_data.as_Data();
- ASSERT_BUG(Span(), e.variant_index < variants.size(), "Variant index out of range");
- const auto& raw_ty = variants[e.variant_index].type;
- if( monomorphise_type_needed(raw_ty) ) {
- return *tmp_ty_ptr = monomorph(raw_ty);
- }
- else {
- return raw_ty;
- }
- }
- else
- {
- const auto& unm = *te.binding.as_Union();
- ASSERT_BUG(Span(), e.variant_index < unm.m_variants.size(), "Variant index out of range");
- const auto& variant = unm.m_variants[e.variant_index];
- const auto& var_ty = variant.second.ent;
-
- if( monomorphise_type_needed(var_ty) ) {
- *tmp_ty_ptr = monomorphise_type(pp.sp, unm.m_params, te.path.m_data.as_Generic().m_params, variant.second.ent);
- tv.m_resolve.expand_associated_types(pp.sp, *tmp_ty_ptr);
- return *tmp_ty_ptr;
- }
- else {
- return var_ty;
- }
- }
- )
- )
- }
)
)
- return blank;
+ assert(ty_p);
+ for(const auto& w : lv.m_wrappers)
+ {
+ ty_p = &mir_res.get_unwrapped_type(tmp, w, *ty_p);
+ if( w.is_Deref() )
+ {
+ tv.visit_type(*ty_p);
+ }
+ }
}
- static void visit_param(TypeVisitor& tv, const Trans_Params& pp, const ::HIR::Function& fcn, const ::MIR::Param& p)
+ void visit_const(const ::MIR::Constant& p)
+ {
+ }
+
+ void visit_param(const ::MIR::Param& p)
{
TU_MATCHA( (p), (e),
(LValue,
- H::visit_lvalue(tv, pp, fcn, e);
+ this->visit_lvalue(e);
),
(Constant,
+ this->visit_const(e);
)
)
}
};
+ MirVisitor mir_visit(tv, pp, fcn, mir_res);
for(const auto& stmt : block.statements)
{
TU_MATCHA( (stmt), (se),
(Drop,
- H::visit_lvalue(tv,pp,fcn, se.slot);
+ mir_visit.visit_lvalue(se.slot);
),
(SetDropFlag,
),
(Asm,
for(const auto& v : se.outputs)
- H::visit_lvalue(tv,pp,fcn, v.second);
+ mir_visit.visit_lvalue(v.second);
for(const auto& v : se.inputs)
- H::visit_lvalue(tv,pp,fcn, v.second);
+ mir_visit.visit_lvalue(v.second);
),
(ScopeEnd,
),
(Assign,
- H::visit_lvalue(tv,pp,fcn, se.dst);
+ mir_visit.visit_lvalue(se.dst);
TU_MATCHA( (se.src), (re),
(Use,
- H::visit_lvalue(tv,pp,fcn, re);
+ mir_visit.visit_lvalue(re);
),
(Constant,
+ mir_visit.visit_const(re);
),
(SizedArray,
- H::visit_param(tv,pp,fcn, re.val);
+ mir_visit.visit_param(re.val);
),
(Borrow,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ mir_visit.visit_lvalue(re.val);
),
(Cast,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ mir_visit.visit_lvalue(re.val);
),
(BinOp,
- H::visit_param(tv,pp,fcn, re.val_l);
- H::visit_param(tv,pp,fcn, re.val_l);
+ mir_visit.visit_param(re.val_l);
+ mir_visit.visit_param(re.val_r);
),
(UniOp,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ mir_visit.visit_lvalue(re.val);
),
(DstMeta,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ mir_visit.visit_lvalue(re.val);
),
(DstPtr,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ mir_visit.visit_lvalue(re.val);
),
(MakeDst,
- H::visit_param(tv,pp,fcn, re.ptr_val);
- H::visit_param(tv,pp,fcn, re.meta_val);
+ mir_visit.visit_param(re.ptr_val);
+ mir_visit.visit_param(re.meta_val);
),
(Tuple,
for(const auto& v : re.vals)
- H::visit_param(tv,pp,fcn, v);
+ mir_visit.visit_param(v);
),
(Array,
for(const auto& v : re.vals)
- H::visit_param(tv,pp,fcn, v);
+ mir_visit.visit_param(v);
),
(Variant,
- H::visit_param(tv,pp,fcn, re.val);
+ mir_visit.visit_param(re.val);
),
(Struct,
for(const auto& v : re.vals)
- H::visit_param(tv,pp,fcn, v);
+ mir_visit.visit_param(v);
)
)
)
@@ -983,32 +922,65 @@ void Trans_Enumerate_Types(EnumState& state)
(Goto, ),
(Panic, ),
(If,
- H::visit_lvalue(tv,pp,fcn, te.cond);
+ mir_visit.visit_lvalue(te.cond);
),
(Switch,
- H::visit_lvalue(tv,pp,fcn, te.val);
+ mir_visit.visit_lvalue(te.val);
),
(SwitchValue,
- H::visit_lvalue(tv,pp,fcn, te.val);
+ mir_visit.visit_lvalue(te.val);
),
(Call,
- if( te.fcn.is_Value() )
- H::visit_lvalue(tv,pp,fcn, te.fcn.as_Value());
- else if( te.fcn.is_Intrinsic() )
+ if(const auto* e = te.fcn.opt_Value() )
+ {
+ mir_visit.visit_lvalue(*e);
+ }
+ else if(const auto* e = te.fcn.opt_Intrinsic())
{
- for(const auto& ty : te.fcn.as_Intrinsic().params.m_types)
+ for(const auto& ty : e->params.m_types)
tv.visit_type(monomorph(ty));
}
- H::visit_lvalue(tv,pp,fcn, te.ret_val);
+ else
+ {
+ // Paths don't need visiting?
+ }
+ mir_visit.visit_lvalue(te.ret_val);
for(const auto& arg : te.args)
- H::visit_param(tv,pp,fcn, arg);
+ mir_visit.visit_param(arg);
)
)
}
}
}
+ }; // struct TypeVisitor
+} // namespace <empty>
+
+// Enumerate types required for the enumerated items
+void Trans_Enumerate_Types(EnumState& state)
+{
+ static Span sp;
+ TypeVisitor tv { state.crate, state.rv.m_types };
+
+ unsigned int types_count = 0;
+ bool constructors_added;
+ do
+ {
+ // Visit all functions that haven't been type-visited yet
+ for(unsigned int i = 0; i < state.fcns_to_type_visit.size(); i++)
+ {
+ auto* p = state.fcns_to_type_visit[i];
+ assert(p->path);
+ assert(p->ptr);
+ auto& fcn_path = *p->path;
+ const auto& fcn = *p->ptr;
+ const auto& pp = p->pp;
+
+ TRACE_FUNCTION_F("Function " << fcn_path);
+ tv.visit_function(fcn_path, fcn, pp);
+ }
state.fcns_to_type_visit.clear();
// TODO: Similarly restrict revisiting of statics.
+ // - Challenging, as they're stored as a std::map
for(const auto& ent : state.rv.m_statics)
{
TRACE_FUNCTION_F("Enumerate static " << ent.first);
@@ -1024,8 +996,7 @@ void Trans_Enumerate_Types(EnumState& state)
const auto& gpath = ent.first.m_data.as_UfcsKnown().trait;
const auto& trait = state.crate.get_trait_by_path(sp, gpath.m_path);
- auto vtable_ty_spath = gpath.m_path;
- vtable_ty_spath.m_components.back() += "#vtable";
+ const auto& vtable_ty_spath = trait.m_vtable_path;
const auto& vtable_ref = state.crate.get_struct_by_path(sp, vtable_ty_spath);
// Copy the param set from the trait in the trait object
::HIR::PathParams vtable_params = gpath.m_params.clone();
@@ -1056,27 +1027,16 @@ void Trans_Enumerate_Types(EnumState& state)
if( ty.m_data.is_Path() )
{
const auto& te = ty.m_data.as_Path();
- const ::HIR::TraitMarkings* markings_ptr = nullptr;
- TU_MATCHA( (te.binding), (tpb),
- (Unbound, ),
- (Opaque, ),
- (Struct,
- markings_ptr = &tpb->m_markings;
- ),
- (Union,
- markings_ptr = &tpb->m_markings;
- ),
- (Enum,
- markings_ptr = &tpb->m_markings;
- )
- )
- ASSERT_BUG(Span(), markings_ptr, "Path binding not set correctly - " << ty);
+ ASSERT_BUG(sp, te.path.m_data.is_Generic(), "Non-Generic type path after enumeration - " << ty);
+ const auto& gp = te.path.m_data.as_Generic();
+ const ::HIR::TraitMarkings* markings_ptr = te.binding.get_trait_markings();
+ ASSERT_BUG(sp, markings_ptr, "Path binding not set correctly - " << ty);
// If the type has a drop impl, and it's either defined in this crate or has params (and thus was monomorphised)
- if( markings_ptr->has_drop_impl && (te.path.m_data.as_Generic().m_path.m_crate_name == state.crate.m_crate_name || te.path.m_data.as_Generic().m_params.has_params()) )
+ if( markings_ptr->has_drop_impl && (gp.m_path.m_crate_name == state.crate.m_crate_name || gp.m_params.has_params()) )
{
// Add the Drop impl to the codegen list
- Trans_Enumerate_FillFrom_Path(state, ::HIR::Path( ty.clone(), state.crate.get_lang_item_path(sp, "drop"), "drop"), {});
+ Trans_Enumerate_FillFrom_PathMono(state, ::HIR::Path( ty.clone(), state.crate.get_lang_item_path(sp, "drop"), "drop"));
constructors_added = true;
}
}
@@ -1086,7 +1046,7 @@ void Trans_Enumerate_Types(EnumState& state)
// Reqire drop glue for inner type.
// - Should that already exist?
// Requires box_free lang item
- Trans_Enumerate_FillFrom_Path(state, ::HIR::GenericPath( state.crate.get_lang_item_path(sp, "box_free"), { ity->clone() } ), {});;
+ Trans_Enumerate_FillFrom_PathMono(state, ::HIR::GenericPath( state.crate.get_lang_item_path(sp, "box_free"), { ity->clone() } ));
}
}
types_count = state.rv.m_types.size();
@@ -1180,14 +1140,14 @@ namespace {
return true;
}
}
- //{
- // auto it = impl.m_constants.find(e.item);
- // if( it != impl.m_constants.end() )
- // {
- // rv = EntPtr { &it->second.data };
- // return true;
- // }
- //}
+ {
+ auto it = impl.m_constants.find(pe->item);
+ if( it != impl.m_constants.end() )
+ {
+ rv = EntPtr { &it->second.data };
+ return true;
+ }
+ }
return false;
});
return rv;
@@ -1203,23 +1163,24 @@ namespace {
const auto& trait_vi = trait_vi_it->second;
bool is_dynamic = false;
+ bool any_impl = false;
::std::vector<::HIR::TypeRef> best_impl_params;
const ::HIR::TraitImpl* best_impl = nullptr;
resolve.find_impl(sp, pe->trait.m_path, pe->trait.m_params, *pe->type, [&](auto impl_ref, auto is_fuzz) {
DEBUG("[get_ent_fullpath] Found " << impl_ref);
//ASSERT_BUG(sp, !is_fuzz, "Fuzzy match not allowed here");
if( ! impl_ref.m_data.is_TraitImpl() ) {
- DEBUG("Trans impl search found an invalid impl type");
+ DEBUG("Trans impl search found an invalid impl type - " << impl_ref.m_data.tag_str());
is_dynamic = true;
// TODO: This can only really happen if it's a trait object magic impl, which should become a vtable lookup.
return true;
}
+ any_impl = true;
const auto& impl_ref_e = impl_ref.m_data.as_TraitImpl();
const auto& impl = *impl_ref_e.impl;
ASSERT_BUG(sp, impl.m_trait_args.m_types.size() == pe->trait.m_params.m_types.size(), "Trait parameter count mismatch " << impl.m_trait_args << " vs " << pe->trait.m_params);
if( best_impl == nullptr || impl.more_specific_than(*best_impl) ) {
- best_impl = &impl;
bool is_spec = false;
TU_MATCHA( (trait_vi), (ve),
(Constant,
@@ -1233,7 +1194,8 @@ namespace {
(Static,
if( pe->item == "vtable#" ) {
is_spec = true;
- break;
+ DEBUG("VTable, quick return");
+ return true;
}
auto it = impl.m_statics.find(pe->item);
if( it == impl.m_statics.end() ) {
@@ -1251,6 +1213,7 @@ namespace {
is_spec = fit->second.is_specialisable;
)
)
+ best_impl = &impl;
best_impl_params.clear();
for(unsigned int i = 0; i < impl_ref_e.params.size(); i ++)
{
@@ -1269,50 +1232,62 @@ namespace {
});
if( is_dynamic )
return EntPtr::make_AutoGenerate( {} );
- if( !best_impl )
+ if( !any_impl )
return EntPtr {};
- const auto& impl = *best_impl;
+ if( best_impl )
+ {
+ const auto& impl = *best_impl;
- impl_pp.m_types = mv$(best_impl_params);
+ impl_pp.m_types = mv$(best_impl_params);
- TU_MATCHA( (trait_vi), (ve),
- (Constant,
- auto it = impl.m_constants.find(pe->item);
- if( it != impl.m_constants.end() )
- {
+ // Fallback on default/provided items
+ TU_MATCH_HDRA( (trait_vi), {)
+ TU_ARMA(Constant, ve) {
+ auto it = impl.m_constants.find(pe->item);
+ ASSERT_BUG(sp, it != impl.m_constants.end(), "best_impl set, but item not found - " << path);
DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
return EntPtr { &it->second.data };
- }
- TODO(sp, "Associated constant - " << path);
- ),
- (Static,
- if( pe->item == "vtable#" )
- {
- DEBUG("VTable, autogen");
- return EntPtr::make_AutoGenerate( {} );
- }
- auto it = impl.m_statics.find(pe->item);
- if( it != impl.m_statics.end() )
- {
+ }
+ TU_ARMA(Static, ve) {
+ assert(pe->item != "vtable#");
+ auto it = impl.m_statics.find(pe->item);
+ ASSERT_BUG(sp, it != impl.m_statics.end(), "best_impl set, but item not found - " << path);
DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
return EntPtr { &it->second.data };
- }
- TODO(sp, "Associated static - " << path);
- ),
- (Function,
- auto fit = impl.m_methods.find(pe->item);
- if( fit != impl.m_methods.end() )
- {
+ }
+ TU_ARMA(Function, ve) {
+ auto fit = impl.m_methods.find(pe->item);
+ ASSERT_BUG(sp, fit != impl.m_methods.end(), "best_impl set, but item not found - " << path);
DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
return EntPtr { &fit->second.data };
+ }
}
- impl_pp = pe->trait.m_params.clone();
- // HACK! By adding a new parameter here, the MIR will always be monomorphised
- impl_pp.m_types.push_back( ::HIR::TypeRef() );
- return EntPtr { &ve };
- )
- )
- BUG(sp, "");
+ }
+ else
+ {
+ // Fallback on default/provided items
+ TU_MATCH_HDRA( (trait_vi), {)
+ TU_ARMA(Constant, ve) {
+ TODO(sp, "Associated constant - " << path);
+ }
+ TU_ARMA(Static, ve) {
+ if( pe->item == "vtable#" )
+ {
+ DEBUG("VTable, autogen");
+ return EntPtr::make_AutoGenerate( {} );
+ }
+ TODO(sp, "Associated static - " << path);
+ }
+ TU_ARMA(Function, ve) {
+ ASSERT_BUG(sp, ve.m_code.m_mir, "Attempting to use default method with no body MIR - " << path);
+ impl_pp = pe->trait.m_params.clone();
+ // HACK! By adding a new parameter here, the MIR will always be monomorphised
+ impl_pp.m_types.push_back( ::HIR::TypeRef() );
+ return EntPtr { &ve };
+ }
+ }
+ }
+ throw "unreachable";
}
else
{
@@ -1323,12 +1298,75 @@ namespace {
}
}
+namespace MIR {
+ struct EnumCache
+ {
+ ::std::vector<const ::HIR::Path*> paths;
+ ::std::vector<const ::HIR::TypeRef*> typeids;
+ EnumCache()
+ {
+ }
+ void insert_path(const ::HIR::Path& new_path)
+ {
+ for(const auto* p : this->paths)
+ if( *p == new_path )
+ return ;
+ this->paths.push_back(&new_path);
+ }
+ void insert_typeid(const ::HIR::TypeRef& new_ty)
+ {
+ for(const auto* p : this->typeids)
+ if( *p == new_ty )
+ return ;
+ this->typeids.push_back(&new_ty);
+ }
+
+ void apply(EnumState& state, const Trans_Params& pp) const
+ {
+ for(const auto* ty_p : this->typeids)
+ {
+ state.rv.m_typeids.insert( pp.monomorph(state.crate, *ty_p) );
+ }
+ for(const auto& path : this->paths)
+ {
+ Trans_Enumerate_FillFrom_Path(state, *path, pp);
+ }
+ }
+ };
+ EnumCachePtr::~EnumCachePtr()
+ {
+ delete this->p;
+ this->p = nullptr;
+ }
+}
+
void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, const Trans_Params& pp)
{
- TRACE_FUNCTION_F(path);
- Span sp;
auto path_mono = pp.monomorph(state.crate, path);
- DEBUG("- " << path_mono);
+ Trans_Enumerate_FillFrom_PathMono(state, mv$(path_mono));
+}
+void Trans_Enumerate_FillFrom_PathMono(EnumState& state, ::HIR::Path path_mono)
+{
+ TRACE_FUNCTION_F(path_mono);
+ Span sp;
+ // TODO: If already in the list, return early
+ if( state.rv.m_functions.count(path_mono) ) {
+ DEBUG("> Already done function");
+ return ;
+ }
+ if( state.rv.m_statics.count(path_mono) ) {
+ DEBUG("> Already done static");
+ return ;
+ }
+ if( state.rv.m_constants.count(path_mono) ) {
+ DEBUG("> Already done constant");
+ return ;
+ }
+ if( state.rv.m_vtables.count(path_mono) ) {
+ DEBUG("> Already done vtable");
+ return ;
+ }
+
Trans_Params sub_pp(sp);
TU_MATCHA( (path_mono.m_data), (pe),
(Generic,
@@ -1344,17 +1382,17 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co
sub_pp.self_type = pe.type->clone();
),
(UfcsUnknown,
- BUG(sp, "UfcsUnknown - " << path);
+ BUG(sp, "UfcsUnknown - " << path_mono);
)
)
// Get the item type
// - Valid types are Function and Static
auto item_ref = get_ent_fullpath(sp, state.crate, path_mono, sub_pp.pp_impl);
- TU_MATCHA( (item_ref), (e),
- (NotFound,
+ TU_MATCH_HDRA( (item_ref), {)
+ TU_ARMA(NotFound, e) {
BUG(sp, "Item not found for " << path_mono);
- ),
- (AutoGenerate,
+ }
+ TU_ARMA(AutoGenerate, e) {
if( path_mono.m_data.is_Generic() )
{
// Leave generation of struct/enum constructors to codgen
@@ -1376,58 +1414,102 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co
// Must have been a dynamic dispatch request, just leave as-is
}
// - <fn(...) as Fn*>::call*
- else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().type->m_data.is_Function() )
+ else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().type->m_data.is_Function() && (
+ path_mono.m_data.as_UfcsKnown().trait.m_path == state.crate.get_lang_item_path_opt("fn")
+ || path_mono.m_data.as_UfcsKnown().trait.m_path == state.crate.get_lang_item_path_opt("fn_mut")
+ || path_mono.m_data.as_UfcsKnown().trait.m_path == state.crate.get_lang_item_path_opt("fn_once")
+ ) )
{
// Must have been a dynamic dispatch request, just leave as-is
}
+ // <* as Clone>::clone
+ else if( TARGETVER_1_29 && path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().trait == state.crate.get_lang_item_path_opt("clone") )
+ {
+ const auto& pe = path_mono.m_data.as_UfcsKnown();
+ ASSERT_BUG(sp, pe.item == "clone" || pe.item == "clone_from", "Unexpected Clone method called, " << path_mono);
+ const auto& inner_ty = *pe.type;
+ // If this is !Copy, then we need to ensure that the inner type's clone impls are also available
+ ::StaticTraitResolve resolve { state.crate };
+ if( !resolve.type_is_copy(sp, inner_ty) )
+ {
+ auto enum_impl = [&](const ::HIR::TypeRef& ity) {
+ if( !resolve.type_is_copy(sp, ity) )
+ {
+ Trans_Enumerate_FillFrom_PathMono(state, ::HIR::Path(ity.clone(), pe.trait.clone(), pe.item));
+ }
+ };
+ if( const auto* te = inner_ty.m_data.opt_Tuple() ) {
+ for(const auto& ity : *te)
+ {
+ enum_impl(ity);
+ }
+ }
+ else if( const auto* te = inner_ty.m_data.opt_Array() ) {
+ enum_impl(*te->inner);
+ }
+ else if( TU_TEST2(inner_ty.m_data, Path, .path.m_data, Generic, .m_path.m_components.back().compare(0, 8, "closure#") == 0) ) {
+ const auto& gp = inner_ty.m_data.as_Path().path.m_data.as_Generic();
+ const auto& str = state.crate.get_struct_by_path(sp, gp.m_path);
+ Trans_Params p;
+ p.sp = sp;
+ p.pp_impl = gp.m_params.clone();
+ for(const auto& fld : str.m_data.as_Tuple())
+ {
+ ::HIR::TypeRef tmp;
+ const auto& ty_m = monomorphise_type_needed(fld.ent) ? (tmp = p.monomorph(resolve, fld.ent)) : fld.ent;
+ enum_impl(ty_m);
+ }
+ }
+ else {
+ BUG(sp, "Unhandled magic clone in enumerate - " << inner_ty);
+ }
+ }
+ // Add this type to a list of types that will have the impl auto-generated
+ state.rv.auto_clone_impls.insert( inner_ty.clone() );
+ }
else
{
BUG(sp, "AutoGenerate returned for unknown path type - " << path_mono);
}
- ),
- (Function,
+ }
+ TU_ARMA(Function, e) {
// Add this path (monomorphised) to the queue
state.enum_fcn(mv$(path_mono), *e, mv$(sub_pp));
- ),
- (Static,
+ }
+ TU_ARMA(Static, e) {
if( auto* ptr = state.rv.add_static(mv$(path_mono)) )
{
Trans_Enumerate_FillFrom(state, *e, *ptr, mv$(sub_pp));
}
- ),
- (Constant,
- Trans_Enumerate_FillFrom_Literal(state, e->m_value_res, sub_pp);
- )
- )
+ }
+ TU_ARMA(Constant, e) {
+ if( e->m_value_res.is_Defer() )
+ {
+ if( auto* slot = state.rv.add_const(mv$(path_mono)) )
+ {
+ MIR::EnumCache es;
+ Trans_Enumerate_FillFrom_MIR(es, *e->m_value.m_mir);
+ es.apply(state, sub_pp);
+ slot->ptr = e;
+ slot->pp = ::std::move(sub_pp);
+ }
+ }
+ else
+ {
+ Trans_Enumerate_FillFrom_Literal(state, e->m_value_res, sub_pp);
+ }
+ }
+ }
}
-void Trans_Enumerate_FillFrom_MIR_LValue(EnumState& state, const ::MIR::LValue& lv, const Trans_Params& pp)
+
+void Trans_Enumerate_FillFrom_MIR_LValue(MIR::EnumCache& state, const ::MIR::LValue& lv)
{
- TU_MATCHA( (lv), (e),
- (Return,
- ),
- (Argument,
- ),
- (Local,
- ),
- (Static,
- Trans_Enumerate_FillFrom_Path(state, e, pp);
- ),
- (Field,
- Trans_Enumerate_FillFrom_MIR_LValue(state, *e.val, pp);
- ),
- (Deref,
- Trans_Enumerate_FillFrom_MIR_LValue(state, *e.val, pp);
- ),
- (Index,
- Trans_Enumerate_FillFrom_MIR_LValue(state, *e.val, pp);
- Trans_Enumerate_FillFrom_MIR_LValue(state, *e.idx, pp);
- ),
- (Downcast,
- Trans_Enumerate_FillFrom_MIR_LValue(state, *e.val, pp);
- )
- )
+ if( lv.m_root.is_Static() )
+ {
+ state.insert_path(lv.m_root.as_Static());
+ }
}
-void Trans_Enumerate_FillFrom_MIR_Constant(EnumState& state, const ::MIR::Constant& c, const Trans_Params& pp)
+void Trans_Enumerate_FillFrom_MIR_Constant(MIR::EnumCache& state, const ::MIR::Constant& c)
{
TU_MATCHA( (c), (ce),
(Int, ),
@@ -1437,21 +1519,22 @@ void Trans_Enumerate_FillFrom_MIR_Constant(EnumState& state, const ::MIR::Consta
(Bytes, ),
(StaticString, ), // String
(Const,
- //Trans_Enumerate_FillFrom_Path(state, ce.p, pp);
+ // - Check if this constant has a value of Defer
+ state.insert_path(*ce.p);
),
(ItemAddr,
- Trans_Enumerate_FillFrom_Path(state, ce, pp);
+ state.insert_path(*ce);
)
)
}
-void Trans_Enumerate_FillFrom_MIR_Param(EnumState& state, const ::MIR::Param& p, const Trans_Params& pp)
+void Trans_Enumerate_FillFrom_MIR_Param(MIR::EnumCache& state, const ::MIR::Param& p)
{
TU_MATCHA( (p), (e),
- (LValue, Trans_Enumerate_FillFrom_MIR_LValue(state, e, pp); ),
- (Constant, Trans_Enumerate_FillFrom_MIR_Constant(state, e, pp); )
+ (LValue, Trans_Enumerate_FillFrom_MIR_LValue(state, e); ),
+ (Constant, Trans_Enumerate_FillFrom_MIR_Constant(state, e); )
)
}
-void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code, const Trans_Params& pp)
+void Trans_Enumerate_FillFrom_MIR(MIR::EnumCache& state, const ::MIR::Function& code)
{
for(const auto& bb : code.blocks)
{
@@ -1460,63 +1543,63 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
TU_MATCHA((stmt), (se),
(Assign,
DEBUG("- " << se.dst << " = " << se.src);
- Trans_Enumerate_FillFrom_MIR_LValue(state, se.dst, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, se.dst);
TU_MATCHA( (se.src), (e),
(Use,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e);
),
(Constant,
- Trans_Enumerate_FillFrom_MIR_Constant(state, e, pp);
+ Trans_Enumerate_FillFrom_MIR_Constant(state, e);
),
(SizedArray,
- Trans_Enumerate_FillFrom_MIR_Param(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val);
),
(Borrow,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(Cast,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(BinOp,
- Trans_Enumerate_FillFrom_MIR_Param(state, e.val_l, pp);
- Trans_Enumerate_FillFrom_MIR_Param(state, e.val_r, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val_l);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val_r);
),
(UniOp,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(DstMeta,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(DstPtr,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(MakeDst,
- Trans_Enumerate_FillFrom_MIR_Param(state, e.ptr_val, pp);
- Trans_Enumerate_FillFrom_MIR_Param(state, e.meta_val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.ptr_val);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.meta_val);
),
(Tuple,
for(const auto& val : e.vals)
- Trans_Enumerate_FillFrom_MIR_Param(state, val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, val);
),
(Array,
for(const auto& val : e.vals)
- Trans_Enumerate_FillFrom_MIR_Param(state, val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, val);
),
(Variant,
- Trans_Enumerate_FillFrom_MIR_Param(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val);
),
(Struct,
for(const auto& val : e.vals)
- Trans_Enumerate_FillFrom_MIR_Param(state, val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, val);
)
)
),
(Asm,
DEBUG("- asm! ...");
for(const auto& v : se.inputs)
- Trans_Enumerate_FillFrom_MIR_LValue(state, v.second, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, v.second);
for(const auto& v : se.outputs)
- Trans_Enumerate_FillFrom_MIR_LValue(state, v.second, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, v.second);
),
(SetDropFlag,
),
@@ -1524,7 +1607,7 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
),
(Drop,
DEBUG("- DROP " << se.slot);
- Trans_Enumerate_FillFrom_MIR_LValue(state, se.slot, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, se.slot);
// TODO: Ensure that the drop glue for this type is generated
)
)
@@ -1537,32 +1620,32 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
(Goto, ),
(Panic, ),
(If,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.cond, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.cond);
),
(Switch,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(SwitchValue,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.val);
),
(Call,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.ret_val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e.ret_val);
TU_MATCHA( (e.fcn), (e2),
(Value,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e2, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(state, e2);
),
(Path,
- Trans_Enumerate_FillFrom_Path(state, e2, pp);
+ state.insert_path(e2);
),
(Intrinsic,
if( e2.name == "type_id" ) {
// Add <T>::#type_id to the enumerate list
- state.rv.m_typeids.insert( pp.monomorph(state.crate, e2.params.m_types.at(0)) );
+ state.insert_typeid(e2.params.m_types.at(0));
}
)
)
for(const auto& arg : e.args)
- Trans_Enumerate_FillFrom_MIR_Param(state, arg, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, arg);
)
)
}
@@ -1582,7 +1665,7 @@ void Trans_Enumerate_FillFrom_VTable(EnumState& state, ::HIR::Path vtable_path,
{
DEBUG("- " << m.second.first << " = " << m.second.second << " :: " << m.first);
auto gpath = monomorphise_genericpath_with(sp, m.second.second, monomorph_cb_trait, false);
- Trans_Enumerate_FillFrom_Path(state, ::HIR::Path(type.clone(), mv$(gpath), m.first), {});
+ Trans_Enumerate_FillFrom_PathMono(state, ::HIR::Path(type.clone(), mv$(gpath), m.first));
}
}
@@ -1591,6 +1674,9 @@ void Trans_Enumerate_FillFrom_Literal(EnumState& state, const ::HIR::Literal& li
TU_MATCHA( (lit), (e),
(Invalid,
),
+ (Defer,
+ // TODO: Bug?
+ ),
(List,
for(const auto& v : e)
Trans_Enumerate_FillFrom_Literal(state, v, pp);
@@ -1621,7 +1707,7 @@ namespace {
TU_IFLET( ::HIR::ValueItem, vi.second->ent, Function, i,
if( i.m_code.m_mir && i.m_linkage.name != "" && i.m_linkage.name == name )
{
- out_path = (mod_path + vi.first.c_str()).get_simple_path();
+ out_path = (mod_path + vi.first).get_simple_path();
return &i;
}
)
@@ -1630,7 +1716,7 @@ namespace {
for(const auto& ti : mod.m_mod_items)
{
TU_IFLET( ::HIR::TypeItem, ti.second->ent, Module, i,
- if( auto rv = find_function_by_link_name(i, mod_path + ti.first.c_str(), name, out_path) )
+ if( auto rv = find_function_by_link_name(i, mod_path + ti.first, name, out_path) )
return rv;
)
}
@@ -1658,7 +1744,15 @@ void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Function& function,
TRACE_FUNCTION_F("Function pp=" << pp.pp_method<<"+"<<pp.pp_impl);
if( function.m_code.m_mir )
{
- Trans_Enumerate_FillFrom_MIR(state, *function.m_code.m_mir, pp);
+ const auto& mir_fcn = *function.m_code.m_mir;
+ if( !mir_fcn.trans_enum_state )
+ {
+ auto* esp = new MIR::EnumCache();
+ Trans_Enumerate_FillFrom_MIR(*esp, *function.m_code.m_mir);
+ mir_fcn.trans_enum_state = ::MIR::EnumCachePtr(esp);
+ }
+ // TODO: Ensure that all types have drop glue generated too? (Iirc this is unconditional currently)
+ mir_fcn.trans_enum_state->apply(state, pp);
}
else
{
@@ -1692,4 +1786,3 @@ void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Static& item, Trans
out_stat.ptr = &item;
out_stat.pp = mv$(pp);
}
-