From 6d16e113d9b01e10f017ce2ecd3bcd2552b6b3e5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 18 Nov 2016 12:46:57 +0800 Subject: HIR Expand - Erased types replacment --- src/hir_expand/erased_types.cpp | 137 +++++++++++++++++++++++++++++++++++++++ src/hir_expand/main_bindings.hpp | 6 ++ src/main.cpp | 4 ++ 3 files changed, 147 insertions(+) create mode 100644 src/hir_expand/erased_types.cpp (limited to 'src') diff --git a/src/hir_expand/erased_types.cpp b/src/hir_expand/erased_types.cpp new file mode 100644 index 00000000..4da148d0 --- /dev/null +++ b/src/hir_expand/erased_types.cpp @@ -0,0 +1,137 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * hir_expand/erased_types.cpp + * - HIR Expansion - Replace `impl Trait` with the real type + */ +#include +#include +#include +#include +#include "main_bindings.hpp" + +namespace { + + + class ExprVisitor_Extract: + public ::HIR::ExprVisitorDef + { + const StaticTraitResolve& m_resolve; + + public: + ExprVisitor_Extract(const StaticTraitResolve& resolve): + m_resolve(resolve) + { + } + + void visit_root(::HIR::ExprPtr& root) + { + root->visit(*this); + for(auto& ty : root.m_bindings) + visit_type(ty); + for(auto& ty : root.m_erased_types) + visit_type(ty); + } + + void visit_type(::HIR::TypeRef& ty) override + { + static Span sp; + + if( ty.m_data.is_ErasedType() ) + { + TRACE_FUNCTION_FR(ty, ty); + + const auto& e = ty.m_data.as_ErasedType(); + + ::HIR::PathParams impl_params; // cache. + t_cb_generic monomorph_cb; + const ::HIR::Function* fcn_ptr = nullptr; + TU_MATCHA( (e.m_origin.m_data), (pe), + (UfcsUnknown, + BUG(Span(), "UfcsUnknown in ErasedType - " << ty); + ), + (Generic, + monomorph_cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pe.m_params); + fcn_ptr = &m_resolve.m_crate.get_function_by_path(sp, pe.m_path); + ), + (UfcsKnown, + // NOTE: This isn't possible yet (will it be? or will it expand to an associated type?) + TODO(sp, "Replace ErasedType - " << ty << " with source (UfcsKnown)"); + ), + (UfcsInherent, + // 1. Find correct impl block for the path + const ::HIR::TypeImpl* impl_ptr = nullptr; + m_resolve.m_crate.find_type_impls(*pe.type, [&](const auto& ty)->const auto& { return ty; }, + [&](const auto& impl) { + DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type); + auto it = impl.m_methods.find(pe.item); + if( it == impl.m_methods.end() ) + return false; + fcn_ptr = &it->second.data; + impl_ptr = &impl; + return true; + }); + ASSERT_BUG(sp, fcn_ptr, "Failed to locate function " << e.m_origin); + assert(impl_ptr); + + // 2. Obtain monomorph_cb (including impl params) + impl_params.m_types.resize(impl_ptr->m_params.m_types.size()); + impl_ptr->m_type .match_test_generics(sp, *pe.type, [](const auto& x)->const auto&{return x;}, [&](auto idx, const auto& ty) { + assert( idx < impl_params.m_types.size() ); + impl_params.m_types[idx] = ty.clone(); + return ::HIR::Compare::Equal; + }); + for(const auto& t : impl_params.m_types) + if( t == ::HIR::TypeRef() ) + TODO(sp, "Handle ErasedType where an impl parameter comes from a bound - " << e.m_origin); + + monomorph_cb = monomorphise_type_get_cb(sp, &*pe.type, &impl_params, &pe.params); + ) + ) + assert(fcn_ptr); + const auto& fcn = *fcn_ptr; + const auto& erased_types = fcn.m_code.m_erased_types; + + ASSERT_BUG(sp, e.m_index < erased_types.size(), "Erased type index out of range for " << e.m_origin << " - " << e.m_index << " >= " << erased_types.size()); + const auto& tpl = erased_types[e.m_index]; + + auto new_ty = monomorphise_type_with(sp, tpl, monomorph_cb); + DEBUG("> " << ty << " => " << new_ty); + ty = mv$(new_ty); + // Recurse (TODO: Cleanly prevent infinite recursion - TRACE_FUNCTION does crude prevention) + visit_type(ty); + } + else + { + ::HIR::ExprVisitorDef::visit_type(ty); + } + } + }; + + class OuterVisitor: + public ::HIR::Visitor + { + StaticTraitResolve m_resolve; + public: + OuterVisitor(const ::HIR::Crate& crate): + m_resolve(crate) + {} + + void visit_expr(::HIR::ExprPtr& exp) override + { + if( exp ) + { + ExprVisitor_Extract ev(m_resolve); + ev.visit_root( exp ); + } + } + }; +} + +void HIR_Expand_ErasedType(::HIR::Crate& crate) +{ + OuterVisitor ov(crate); + ov.visit_crate( crate ); +} + diff --git a/src/hir_expand/main_bindings.hpp b/src/hir_expand/main_bindings.hpp index 5de002be..8d495c19 100644 --- a/src/hir_expand/main_bindings.hpp +++ b/src/hir_expand/main_bindings.hpp @@ -1,4 +1,9 @@ /* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * hir_expand/main_bindings.hpp + * - Functions defined in this folder that are called by main */ #pragma once @@ -10,3 +15,4 @@ extern void HIR_Expand_AnnotateUsage(::HIR::Crate& crate); extern void HIR_Expand_Closures(::HIR::Crate& crate); extern void HIR_Expand_UfcsEverything(::HIR::Crate& crate); extern void HIR_Expand_Reborrows(::HIR::Crate& crate); +extern void HIR_Expand_ErasedType(::HIR::Crate& crate); diff --git a/src/main.cpp b/src/main.cpp index 0802d2d4..eb177268 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,7 @@ void init_debug_list() g_debug_disable_map.insert( "Expand HIR Closures" ); g_debug_disable_map.insert( "Expand HIR Calls" ); g_debug_disable_map.insert( "Expand HIR Reborrows" ); + g_debug_disable_map.insert( "Expand HIR ErasedType" ); g_debug_disable_map.insert( "Typecheck Expressions (validate)" ); g_debug_disable_map.insert( "Dump HIR" ); @@ -345,6 +346,9 @@ int main(int argc, char *argv[]) CompilePhaseV("Expand HIR Reborrows", [&]() { HIR_Expand_Reborrows(*hir_crate); }); + CompilePhaseV("Expand HIR ErasedType", [&]() { + HIR_Expand_ErasedType(*hir_crate); + }); CompilePhaseV("Dump HIR", [&]() { ::std::ofstream os (FMT(params.outfile << "_2_hir.rs")); HIR_Dump( os, *hir_crate ); -- cgit v1.2.3