From 3fab1f6071718b5456d4c6b33fa5afe8f9a43f71 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 19 Jul 2016 19:41:01 +0800 Subject: HIR - Very rough impl specialisation support in outer typeck --- src/hir/type.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/hir/type.hpp | 1 + src/hir_typeck/expr_cs.cpp | 1 + src/hir_typeck/outer.cpp | 35 ++++++++++++++++-------- src/hir_typeck/static.cpp | 47 ++++++++++++++++++++++++++++++-- src/hir_typeck/static.hpp | 40 ++++++++++++++++++++++----- 6 files changed, 170 insertions(+), 22 deletions(-) diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 7695f066..a27d5dd0 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -351,6 +351,74 @@ Ordering HIR::TypeRef::ord(const ::HIR::TypeRef& x) const ) throw ""; } +bool ::HIR::TypeRef::contains_generics() const +{ + struct H { + static bool vec_contains_generics(const ::std::vector& v) { + for( const auto& t : v ) + if( t.contains_generics() ) + return true; + return false; + } + }; + TU_MATCH(::HIR::TypeRef::Data, (m_data), (te), + (Infer, + return false; + ), + (Diverge, + return false; + ), + (Primitive, + return false; + ), + (Path, + TU_MATCH(::HIR::Path::Data, (te.path.m_data), (tpe), + (Generic, + return H::vec_contains_generics( tpe.m_params.m_types ); + ), + (UfcsInherent, + if( tpe.type->contains_generics() ) + return true; + TODO(Span(), "UfcsInherent"); + ), + (UfcsKnown, + TODO(Span(), "UfcsKnown"); + ), + (UfcsUnknown, + TODO(Span(), "UfcsUnknown"); + ) + ) + ), + (Generic, + return true; + ), + (TraitObject, + TODO(Span(), "TraitObject"); + ), + (Array, + return te.inner->contains_generics(); + ), + (Slice, + return te.inner->contains_generics(); + ), + (Tuple, + return H::vec_contains_generics(te); + ), + (Borrow, + return te.inner->contains_generics(); + ), + (Pointer, + return te.inner->contains_generics(); + ), + (Function, + return H::vec_contains_generics(te.m_arg_types) || te.m_rettype->contains_generics(); + ), + (Closure, + return H::vec_contains_generics(te.m_arg_types) || te.m_rettype->contains_generics(); + ) + ) + throw ""; +} namespace { diff --git a/src/hir/type.hpp b/src/hir/type.hpp index c5d08c5f..f01c0f1d 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -222,6 +222,7 @@ public: bool operator<(const ::HIR::TypeRef& x) const { return ord(x) == OrdLess; } Ordering ord(const ::HIR::TypeRef& x) const; + bool contains_generics() const; // Match generics in `this` with types from `x` // Raises a bug against `sp` if there is a form mismatch or `this` has an infer diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 195e5e66..86304b4a 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -834,6 +834,7 @@ namespace { const auto& des_ty_r = it->second.ent; auto& des_ty_cache = node.m_value_types[it - fields.begin()]; + DEBUG(name << " : " << des_ty_r); if( monomorphise_type_needed(des_ty_r) ) { if( des_ty_cache == ::HIR::TypeRef() ) { des_ty_cache = monomorphise_type_with(node.span(), des_ty_r, monomorph_cb); diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index 22dcaa43..2baa6ec5 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -251,19 +251,30 @@ namespace { e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({}); } else { - ::HIR::TypeRef new_ty; - bool found = m_resolve.find_impl(sp, pe.trait.m_path, pe.trait.m_params, *pe.type, [&](const auto& impl) { - DEBUG("TODO - Extract associated type '"<contains_generics() ) { + // Mark it as opaque (because monomorphisation could change things) + e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({}); + } + else { + auto new_ty = best_impl.get_type(pe.item.c_str()); + if( new_ty == ::HIR::TypeRef() ) { + ERROR(sp, E0000, "Associated type '"<' " << other << ")"); + ), + (BoundedPtr, + return true; + ), + (Bounded, + return true; + ) + ) + throw ""; +} +bool StaticTraitResolve::ImplRef::type_is_specializable(const char* name) const +{ + TU_MATCH(Data, (this->m_data), (e), + (TraitImpl, + if( e.impl == nullptr ) { + // No impl yet? This type is specialisable. + return true; + } + //TODO(Span(), "type_is_specializable - Impl = " << *this << ", Type = " << name); + return true; + ), + (BoundedPtr, + return false; + ), + (Bounded, + return false; + ) + ) + throw ""; +} ::HIR::TypeRef StaticTraitResolve::ImplRef::get_type(const char* name) const { static Span sp; @@ -570,6 +608,9 @@ bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::Generi return it->second.clone(); } ), + (BoundedPtr, + TODO(Span(), *this); + ), (Bounded, TODO(Span(), *this); ) diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp index 22f1e4bd..8c9989f6 100644 --- a/src/hir_typeck/static.hpp +++ b/src/hir_typeck/static.hpp @@ -57,29 +57,55 @@ public: ::std::vector params; const ::HIR::TraitImpl* impl; }), + (BoundedPtr, struct { + const ::HIR::TypeRef* type; + const ::HIR::PathParams* trait_args; + const ::std::map< ::std::string, ::HIR::TypeRef>* assoc; + }), (Bounded, struct { - const ::HIR::TypeRef* type; - const ::HIR::PathParams* trait_args; - const ::std::map< ::std::string, ::HIR::TypeRef>* assoc; + ::HIR::TypeRef type; + ::HIR::PathParams trait_args; + ::std::map< ::std::string, ::HIR::TypeRef> assoc; }) ); Data m_data; + ImplRef(): + m_data(Data::make_TraitImpl({ {}, nullptr })) + {} ImplRef(::std::vector params, const ::HIR::TraitImpl& impl): m_data(Data::make_TraitImpl({ mv$(params), &impl })) {} - ImplRef(const ::HIR::TypeRef& type, const ::HIR::PathParams& args, const ::std::map< ::std::string, ::HIR::TypeRef>& assoc): - m_data(Data::make_Bounded({ &type, &args, &assoc })) + ImplRef(const ::HIR::TypeRef* type, const ::HIR::PathParams* args, const ::std::map< ::std::string, ::HIR::TypeRef>* assoc): + m_data(Data::make_BoundedPtr({ type, mv$(args), mv$(assoc) })) {} + ImplRef(::HIR::TypeRef type, ::HIR::PathParams args, ::std::map< ::std::string, ::HIR::TypeRef> assoc): + m_data(Data::make_Bounded({ mv$(type), mv$(args), mv$(assoc) })) + {} + + bool is_valid() const { + return !(m_data.is_TraitImpl() && m_data.as_TraitImpl().impl == nullptr); + } + + bool more_specific_than(const ImplRef& other) const; + bool type_is_specializable(const char* name) const; ::HIR::TypeRef get_type(const char* name) const; friend ::std::ostream& operator<<(::std::ostream& os, const ImplRef& x) { TU_MATCH(Data, (x.m_data), (e), (TraitImpl, - os << "impl" << e.impl->m_params.fmt_args() << " ?" << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds(); + if( e.impl == nullptr ) { + os << "none"; + } + else { + os << "impl" << e.impl->m_params.fmt_args() << " ?" << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds(); + } + ), + (BoundedPtr, + os << "bound"; ), (Bounded, os << "bound"; @@ -91,7 +117,7 @@ public: /// \brief Lookups /// \{ - typedef ::std::function t_cb_find_impl; + typedef ::std::function t_cb_find_impl; bool find_impl( const Span& sp, -- cgit v1.2.3