diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_conv/bind.cpp | 133 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 89 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 11 | ||||
-rw-r--r-- | src/mir/mir_ptr.hpp | 4 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 88 | ||||
-rw-r--r-- | src/trans/trans_list.hpp | 10 |
6 files changed, 292 insertions, 43 deletions
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index d88a9fbb..a83b70d3 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -9,6 +9,7 @@ #include "main_bindings.hpp" #include <hir/visitor.hpp> #include <hir/expr.hpp> +#include <mir/mir.hpp> #include <algorithm> // std::find_if #include <hir_typeck/static.hpp> @@ -482,6 +483,138 @@ namespace { ExprVisitor v { *this }; (*expr).visit(v); } + else if( expr.m_mir ) + { + struct H { + static void visit_lvalue(Visitor& upper_visitor, ::MIR::LValue& lv) + { + TU_MATCHA( (lv), (e), + (Variable, + ), + (Temporary, + ), + (Argument, + ), + (Return, + ), + (Static, + upper_visitor.visit_path(e, ::HIR::Visitor::PathContext::VALUE); + ), + (Field, + H::visit_lvalue(upper_visitor, *e.val); + ), + (Deref, + H::visit_lvalue(upper_visitor, *e.val); + ), + (Index, + H::visit_lvalue(upper_visitor, *e.val); + H::visit_lvalue(upper_visitor, *e.idx); + ), + (Downcast, + H::visit_lvalue(upper_visitor, *e.val); + ) + ) + } + }; + for(auto& block : expr.m_mir->blocks) + { + for(auto& stmt : block.statements) + { + TU_IFLET(::MIR::Statement, stmt, Assign, se, + H::visit_lvalue(*this, se.dst); + TU_MATCHA( (se.src), (e), + (Use, + H::visit_lvalue(*this, e); + ), + (Constant, + TU_MATCHA( (e), (ce), + (Int, ), + (Uint,), + (Float, ), + (Bool, ), + (Bytes, ), + (StaticString, ), // String + (Const, + // TODO: Should this trigger anything? + ), + (ItemAddr, + this->visit_path(ce, ::HIR::Visitor::PathContext::VALUE); + ) + ) + ), + (SizedArray, + H::visit_lvalue(*this, e.val); + ), + (Borrow, + H::visit_lvalue(*this, e.val); + ), + (Cast, + H::visit_lvalue(*this, e.val); + ), + (BinOp, + H::visit_lvalue(*this, e.val_l); + H::visit_lvalue(*this, e.val_r); + ), + (UniOp, + H::visit_lvalue(*this, e.val); + ), + (DstMeta, + H::visit_lvalue(*this, e.val); + ), + (DstPtr, + H::visit_lvalue(*this, e.val); + ), + (MakeDst, + H::visit_lvalue(*this, e.meta_val); + H::visit_lvalue(*this, e.ptr_val); + ), + (Tuple, + for(auto& val : e.vals) + H::visit_lvalue(*this, val); + ), + (Array, + for(auto& val : e.vals) + H::visit_lvalue(*this, val); + ), + (Variant, + H::visit_lvalue(*this, e.val); + ), + (Struct, + for(auto& val : e.vals) + H::visit_lvalue(*this, val); + ) + ) + ) + else TU_IFLET(::MIR::Statement, stmt, Drop, se, + H::visit_lvalue(*this, se.slot); + ) + else { + } + } + TU_MATCHA( (block.terminator), (te), + (Incomplete, ), + (Return, ), + (Diverge, ), + (Goto, ), + (Panic, ), + (If, + H::visit_lvalue(*this, te.cond); + ), + (Switch, + H::visit_lvalue(*this, te.val); + ), + (Call, + H::visit_lvalue(*this, te.ret_val); + H::visit_lvalue(*this, te.fcn_val); + for(auto& arg : te.args) + H::visit_lvalue(*this, arg); + ) + ) + } + } + else + { + } } }; } diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 5d7f2512..243690ce 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -101,6 +101,11 @@ bool StaticTraitResolve::find_impl( return found_cb( ImplRef(&type, &null_params, &null_assoc), false ); } } + else if( trait_path == m_lang_Sized ) { + if( this->type_is_sized(sp, type) ) { + return found_cb( ImplRef(&type, &null_params, &null_assoc), false ); + } + } } // --- MAGIC IMPLS --- @@ -806,7 +811,12 @@ void StaticTraitResolve::expand_associated_types_inner(const Span& sp, ::HIR::Ty this->expand_associated_types_inner(sp, arg); ), (UfcsInherent, - TODO(sp, "Path - UfcsInherent - " << e.path); + this->expand_associated_types_inner(sp, *e2.type); + for(auto& arg : e2.params.m_types) + this->expand_associated_types_inner(sp, arg); + // TODO: impl params too? + for(auto& arg : e2.impl_params.m_types) + this->expand_associated_types_inner(sp, arg); ), (UfcsKnown, // - Only try resolving if the binding isn't known @@ -1295,3 +1305,80 @@ bool StaticTraitResolve::type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) ) throw ""; } + +bool StaticTraitResolve::type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const +{ + TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e), + (Generic, + if( e.binding == 0xFFFF ) { + // TODO: Self: Sized? + return true; + } + else if( (e.binding >> 8) == 0 ) { + auto idx = e.binding & 0xFF; + assert( m_impl_generics ); + assert( idx < m_impl_generics->m_types.size() ); + return m_impl_generics->m_types[idx].m_is_sized; + } + else if( (e.binding >> 8) == 1 ) { + auto idx = e.binding & 0xFF; + assert( m_item_generics ); + assert( idx < m_item_generics->m_types.size() ); + return m_item_generics->m_types[idx].m_is_sized; + } + else { + BUG(sp, ""); + } + ), + (Path, + auto pp = ::HIR::PathParams(); + // TODO: Destructure? + return true; + //return this->find_impl(sp, m_lang_Sized, &pp, ty, [&](auto , bool){ return true; }, true); + ), + (Diverge, + // The ! type is kinda Copy ... + return true; + ), + (Closure, + return true; + ), + (Infer, + // Shouldn't be hit + return false; + ), + (Borrow, + return true; + ), + (Pointer, + return true; + ), + (Function, + return true; + ), + (Primitive, + // All primitives (except the unsized `str`) are Sized + return e != ::HIR::CoreType::Str; + ), + (Array, + return true; + ), + (Slice, + return false; + ), + (TraitObject, + return false; + ), + (ErasedType, + // NOTE: All erased types are implicitly Sized + return true; + ), + (Tuple, + for(const auto& ty : e) + if( !type_is_sized(sp, ty) ) + return false; + return true; + ) + ) + throw ""; +} diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp index 80b9ed56..b2b259fd 100644 --- a/src/hir_typeck/static.hpp +++ b/src/hir_typeck/static.hpp @@ -23,6 +23,7 @@ public: ::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities; private: ::HIR::SimplePath m_lang_Copy; + ::HIR::SimplePath m_lang_Sized; ::HIR::SimplePath m_lang_Fn; ::HIR::SimplePath m_lang_FnMut; ::HIR::SimplePath m_lang_FnOnce; @@ -33,10 +34,11 @@ public: m_impl_generics(nullptr), m_item_generics(nullptr) { - m_lang_Copy = m_crate.get_lang_item_path(Span(), "copy"); - m_lang_Fn = m_crate.get_lang_item_path(Span(), "fn"); - m_lang_FnMut = m_crate.get_lang_item_path(Span(), "fn_mut"); - m_lang_FnOnce = m_crate.get_lang_item_path(Span(), "fn_once"); + m_lang_Copy = m_crate.get_lang_item_path_opt("copy"); + m_lang_Sized = m_crate.get_lang_item_path_opt("sized"); + m_lang_Fn = m_crate.get_lang_item_path_opt("fn"); + m_lang_FnMut = m_crate.get_lang_item_path_opt("fn_mut"); + m_lang_FnOnce = m_crate.get_lang_item_path_opt("fn_once"); prep_indexes(); } @@ -163,5 +165,6 @@ public: // Common bounds // ------------- bool type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const; + bool type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const; }; diff --git a/src/mir/mir_ptr.hpp b/src/mir/mir_ptr.hpp index 180fd6c3..583b155b 100644 --- a/src/mir/mir_ptr.hpp +++ b/src/mir/mir_ptr.hpp @@ -32,9 +32,9 @@ public: void reset(); - ::MIR::Function& operator->() { return *ptr; } + ::MIR::Function* operator->() { return ptr; } ::MIR::Function& operator*() { return *ptr; } - const ::MIR::Function& operator->() const { return *ptr; } + const ::MIR::Function* operator->() const { return ptr; } const ::MIR::Function& operator*() const { return *ptr; } operator bool() const { return ptr != nullptr; } diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 24c87897..97e510de 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -11,7 +11,8 @@ #include "trans_list.hpp" #include <hir/hir.hpp> #include <mir/mir.hpp> -#include <hir_typeck/common.hpp> +#include <hir_typeck/common.hpp> // monomorph +#include <hir_typeck/static.hpp> // StaticTraitResolve void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Function& function, TransList_Function& fcn_out, Trans_Params pp={}); @@ -20,9 +21,11 @@ void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const : /// Enumerate trans items starting from `::main` (binary crate) TransList Trans_Enumerate_Main(const ::HIR::Crate& crate) { + static Span sp; + TransList rv; auto main_path = ::HIR::SimplePath("", {"main"}); - const auto& fcn = crate.get_function_by_path(Span(), main_path); + const auto& fcn = crate.get_function_by_path(sp, main_path); auto* ptr = rv.add_function(main_path); assert(ptr); @@ -136,6 +139,9 @@ namespace { } EntPtr get_ent_fullpath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path, ::HIR::PathParams& impl_pp) { + TRACE_FUNCTION_F(path); + StaticTraitResolve resolve { crate }; + TU_MATCH(::HIR::Path::Data, (path.m_data), (e), (Generic, return get_ent_simplepath(sp, crate, e.m_path); @@ -182,31 +188,13 @@ namespace { ::std::vector<const ::HIR::TypeRef*> best_impl_params; const ::HIR::TraitImpl* best_impl = nullptr; - crate.find_trait_impls(e.trait.m_path, *e.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) { - DEBUG("Found impl" << impl.m_params.fmt_args() << " " << e.trait.m_path << impl.m_trait_args << " for " << impl.m_type); + resolve.find_impl(sp, e.trait.m_path, e.trait.m_params, *e.type, [&](auto impl_ref, auto is_fuzz) { + DEBUG("Found " << impl_ref); + //ASSERT_BUG(sp, !is_fuzz, "Fuzzy match not allowed here"); + ASSERT_BUG(sp, impl_ref.m_data.is_TraitImpl(), "Trans impl search found an invalid impl type"); + const auto& impl = *impl_ref.m_data.as_TraitImpl().impl; ASSERT_BUG(sp, impl.m_trait_args.m_types.size() == e.trait.m_params.m_types.size(), "Trait parameter count mismatch " << impl.m_trait_args << " vs " << e.trait.m_params); - ::std::vector<const ::HIR::TypeRef*> impl_params; - - auto cb_ident = [](const auto& t)->const auto& { return t; }; - auto cb = [&impl_params,&sp,cb_ident](auto idx, const auto& ty) { - assert( idx < impl_params.size() ); - if( ! impl_params[idx] ) { - impl_params[idx] = &ty; - return ::HIR::Compare::Equal; - } - else { - return impl_params[idx]->compare_with_placeholders(sp, ty, cb_ident); - } - }; - impl_params.resize(impl.m_params.m_types.size()); - auto match = impl.m_type.match_test_generics_fuzz(sp, *e.type, cb_ident, cb); - match &= impl.m_trait_args.match_test_generics_fuzz(sp, e.trait.m_params, cb_ident, cb); - if( match != ::HIR::Compare::Equal ) { - DEBUG("- Match failed (" << match << ") " << *e.type << " \n + " << e.trait.m_params); - return false; - } - if( best_impl == nullptr || impl.more_specific_than(*best_impl) ) { best_impl = &impl; bool is_spec = false; @@ -229,7 +217,7 @@ namespace { is_spec = fit->second.is_specialisable; ) ) - best_impl_params = mv$( impl_params ); + best_impl_params = mv$( impl_ref.m_data.as_TraitImpl().params ); return !is_spec; } return false; @@ -239,7 +227,7 @@ namespace { const auto& impl = *best_impl; for(const auto* ty_ptr : best_impl_params) { - assert( ty_ptr ); + ASSERT_BUG(sp, ty_ptr, "Parameter unset"); impl_pp.m_types.push_back( ty_ptr->clone() ); } @@ -272,18 +260,22 @@ namespace { void Trans_Enumerate_FillFrom_Path(TransList& out, const ::HIR::Crate& crate, const ::HIR::Path& path, const Trans_Params& pp) { + TRACE_FUNCTION_F(path); Span sp; - auto path_mono = pp.monomorph(path); - Trans_Params sub_pp; + auto path_mono = pp.monomorph(crate, path); + Trans_Params sub_pp(sp); TU_MATCHA( (path_mono.m_data), (pe), (Generic, - sub_pp = Trans_Params { sp, pe.m_params.clone() }; + sub_pp.pp_method = pe.m_params.clone(); ), (UfcsKnown, - sub_pp = Trans_Params { sp, pe.params.clone(), {}, pe.type->clone() }; + sub_pp.pp_method = pe.params.clone(); + sub_pp.self_type = pe.type->clone(); ), (UfcsInherent, - sub_pp = Trans_Params { sp, pe.params.clone(), pe.impl_params.clone(), pe.type->clone() }; + sub_pp.pp_method = pe.params.clone(); + sub_pp.pp_impl = pe.impl_params.clone(); + sub_pp.self_type = pe.type->clone(); ), (UfcsUnknown, BUG(sp, "UfcsUnknown - " << path); @@ -479,8 +471,36 @@ t_cb_generic Trans_Params::get_cb() const { return monomorphise_type_get_cb(sp, &self_type, &pp_impl, &pp_method); } -::HIR::Path Trans_Params::monomorph(const ::HIR::Path& p) const +::HIR::Path Trans_Params::monomorph(const ::HIR::Crate& crate, const ::HIR::Path& p) const { - return monomorphise_path_with(sp, p, this->get_cb(), false); + TRACE_FUNCTION_F(p); + auto rv = monomorphise_path_with(sp, p, this->get_cb(), false); + + ::StaticTraitResolve resolve { crate }; + TU_MATCH(::HIR::Path::Data, (rv.m_data), (e2), + (Generic, + for(auto& arg : e2.m_params.m_types) + resolve.expand_associated_types(sp, arg); + ), + (UfcsInherent, + resolve.expand_associated_types(sp, *e2.type); + for(auto& arg : e2.params.m_types) + resolve.expand_associated_types(sp, arg); + // TODO: impl params too? + for(auto& arg : e2.impl_params.m_types) + resolve.expand_associated_types(sp, arg); + ), + (UfcsKnown, + resolve.expand_associated_types(sp, *e2.type); + for(auto& arg : e2.trait.m_params.m_types) + resolve.expand_associated_types(sp, arg); + for(auto& arg : e2.params.m_types) + resolve.expand_associated_types(sp, arg); + ), + (UfcsUnknown, + BUG(sp, "Encountered UfcsUnknown"); + ) + ) + return rv; } diff --git a/src/trans/trans_list.hpp b/src/trans/trans_list.hpp index 278d8795..78ebd264 100644 --- a/src/trans/trans_list.hpp +++ b/src/trans/trans_list.hpp @@ -12,6 +12,7 @@ #include <hir_typeck/common.hpp> namespace HIR { +class Crate; class Function; class Static; } @@ -23,9 +24,14 @@ struct Trans_Params ::HIR::PathParams pp_impl; ::HIR::TypeRef self_type; + Trans_Params() {} + Trans_Params(const Span& sp): + sp(sp) + {} + t_cb_generic get_cb() const; - ::HIR::TypeRef monomorph(const ::HIR::TypeRef& p) const; - ::HIR::Path monomorph(const ::HIR::Path& p) const; + ::HIR::TypeRef monomorph(const ::HIR::Crate& crate, const ::HIR::TypeRef& p) const; + ::HIR::Path monomorph(const ::HIR::Crate& crate, const ::HIR::Path& p) const; }; struct TransList_Function |