diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-11-02 11:07:23 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-11-02 11:07:23 +0800 |
commit | 1d02810c3cf908bfba7c15ae50eb5314603b9d85 (patch) | |
tree | 79dd5e4ef4c3ff79db0912ba546f08e61a7a8c10 /src/trans/enumerate.cpp | |
parent | 7111acba04d72fe4084b1a1f3209ff83efe8614d (diff) | |
parent | 8b53b38f40625ab0510f541d69db3f83332a830a (diff) | |
download | mrust-1d02810c3cf908bfba7c15ae50eb5314603b9d85.tar.gz |
Merge branch 'nightly-1.29' - #95 Working support for rustc 1.29
Diffstat (limited to 'src/trans/enumerate.cpp')
-rw-r--r-- | src/trans/enumerate.cpp | 953 |
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); } - |