diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/hir_expand/erased_types.cpp | 137 | ||||
-rw-r--r-- | src/hir_expand/main_bindings.hpp | 6 | ||||
-rw-r--r-- | src/main.cpp | 4 |
4 files changed, 148 insertions, 1 deletions
@@ -87,7 +87,7 @@ OBJ += hir_typeck/expr_visit.o OBJ += hir_typeck/expr_cs.o OBJ += hir_typeck/expr_check.o OBJ += hir_expand/annotate_value_usage.o hir_expand/closures.o hir_expand/ufcs_everything.o -OBJ += hir_expand/reborrow.o +OBJ += hir_expand/reborrow.o hir_expand/erased_types.o OBJ += mir/mir.o mir/mir_ptr.o OBJ += mir/dump.o OBJ += mir/from_hir.o mir/from_hir_match.o mir/mir_builder.o 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 <hir/visitor.hpp> +#include <hir/expr.hpp> +#include <hir_typeck/static.hpp> +#include <algorithm> +#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 );
|