diff options
-rw-r--r-- | src/hir/hir.cpp | 64 | ||||
-rw-r--r-- | src/hir_typeck/expr.hpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 114 |
3 files changed, 155 insertions, 25 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index ee1d76a5..2441b338 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -30,6 +30,8 @@ namespace HIR { } namespace { + bool matches_genericpath(const ::HIR::GenericParams& params, const ::HIR::GenericPath& left, const ::HIR::GenericPath& right, ::HIR::t_cb_resolve_type ty_res, bool expand_generic); + bool matches_type_int(const ::HIR::GenericParams& params, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) { assert(! left.m_data.is_Infer() ); @@ -70,28 +72,7 @@ namespace { return false; ), (Generic, - if( ple.m_path.m_crate_name != pre.m_path.m_crate_name ) - return false; - if( ple.m_path.m_components.size() != pre.m_path.m_components.size() ) - return false; - for(unsigned int i = 0; i < ple.m_path.m_components.size(); i ++ ) - { - if( ple.m_path.m_components[i] != pre.m_path.m_components[i] ) - return false; - } - - if( ple.m_params.m_types.size() > 0 || pre.m_params.m_types.size() > 0 ) { - if( ple.m_params.m_types.size() != pre.m_params.m_types.size() ) { - return true; - //TODO(Span(), "Match generic paths " << ple << " and " << pre << " - count mismatch"); - } - for( unsigned int i = 0; i < pre.m_params.m_types.size(); i ++ ) - { - if( ! matches_type_int(params, ple.m_params.m_types[i], pre.m_params.m_types[i], ty_res, expand_generic) ) - return false; - } - } - return true; + return matches_genericpath(params, ple, pre, ty_res, expand_generic); ) ) ), @@ -99,8 +80,18 @@ namespace { throw ""; ), (TraitObject, - DEBUG("TODO: Compare " << left << " and " << right); - return false; + if( !matches_genericpath(params, le.m_trait.m_path, re.m_trait.m_path, ty_res, expand_generic) ) + return false; + if( le.m_markers.size() != re.m_markers.size() ) + return false; + for(unsigned int i = 0; i < le.m_markers.size(); i ++) + { + const auto& lm = le.m_markers[i]; + const auto& rm = re.m_markers[i]; + if( !matches_genericpath(params, lm, rm, ty_res, expand_generic) ) + return false; + } + return true; ), (Array, if( ! matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic) ) @@ -141,6 +132,31 @@ namespace { ) return false; } + bool matches_genericpath(const ::HIR::GenericParams& params, const ::HIR::GenericPath& left, const ::HIR::GenericPath& right, ::HIR::t_cb_resolve_type ty_res, bool expand_generic) + { + if( left.m_path.m_crate_name != right.m_path.m_crate_name ) + return false; + if( left.m_path.m_components.size() != right.m_path.m_components.size() ) + return false; + for(unsigned int i = 0; i < left.m_path.m_components.size(); i ++ ) + { + if( left.m_path.m_components[i] != right.m_path.m_components[i] ) + return false; + } + + if( left.m_params.m_types.size() > 0 || right.m_params.m_types.size() > 0 ) { + if( left.m_params.m_types.size() != right.m_params.m_types.size() ) { + return true; + //TODO(Span(), "Match generic paths " << left << " and " << right << " - count mismatch"); + } + for( unsigned int i = 0; i < right.m_params.m_types.size(); i ++ ) + { + if( ! matches_type_int(params, left.m_params.m_types[i], right.m_params.m_types[i], ty_res, expand_generic) ) + return false; + } + } + return true; + } } bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const diff --git a/src/hir_typeck/expr.hpp b/src/hir_typeck/expr.hpp index 43003cf2..6953d0e2 100644 --- a/src/hir_typeck/expr.hpp +++ b/src/hir_typeck/expr.hpp @@ -95,6 +95,8 @@ public: bool pathparams_equal(const ::HIR::PathParams& pps_l, const ::HIR::PathParams& pps_r) const; bool types_equal(const ::HIR::TypeRef& l, const ::HIR::TypeRef& r) const; + void print_type(::std::ostream& os, const ::HIR::TypeRef& tr) const; + /// Adds a local variable binding (type is mutable so it can be inferred if required) void add_local(unsigned int index, const ::std::string& name, ::HIR::TypeRef type); diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp index bb7bd325..1b3d45e4 100644 --- a/src/hir_typeck/expr_context.cpp +++ b/src/hir_typeck/expr_context.cpp @@ -4,6 +4,19 @@ #include <hir/hir.hpp> #include <algorithm> // std::find_if +struct FmtType { + const typeck::TypecheckContext& ctxt; + const ::HIR::TypeRef& ty; + FmtType(const typeck::TypecheckContext& ctxt, const ::HIR::TypeRef& ty): + ctxt(ctxt), + ty(ty) + {} + friend ::std::ostream& operator<<(::std::ostream& os, const FmtType& x) { + x.ctxt.print_type(os, x.ty); + return os; + } +}; + void typeck::TypecheckContext::push_traits(const ::std::vector<::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > >& list) { this->m_traits.insert( this->m_traits.end(), list.begin(), list.end() ); @@ -293,6 +306,105 @@ bool typeck::TypecheckContext::types_equal(const ::HIR::TypeRef& rl, const ::HIR throw ""; } +void typeck::TypecheckContext::print_type(::std::ostream& os, const ::HIR::TypeRef& tr) const +{ + struct H { + static void print_pp(const TypecheckContext& ctxt, ::std::ostream& os, const ::HIR::PathParams& pps) { + if( pps.m_types.size() > 0 ) { + os << "<"; + for(const auto& pp_t : pps.m_types) { + ctxt.print_type(os, pp_t); + os << ","; + } + os << ">"; + } + } + }; + const auto& ty = this->get_type(tr); + TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e), + (Infer, + os << ty; + ), + (Primitive, + os << ty; + ), + (Diverge, os << ty; ), + (Generic, os << ty; ), + (Path, + TU_MATCH(::HIR::Path::Data, (e.path.m_data), (pe), + (Generic, + os << pe.m_path; + H::print_pp(*this, os, pe.m_params); + ), + (UfcsKnown, + os << "<"; + this->print_type(os, *pe.type); + os << " as " << pe.trait.m_path; + H::print_pp(*this, os, pe.trait.m_params); + os << ">::" << pe.item; + H::print_pp(*this, os, pe.params); + ), + (UfcsInherent, + os << "<"; + this->print_type(os, *pe.type); + os << ">::" << pe.item; + H::print_pp(*this, os, pe.params); + ), + (UfcsUnknown, + BUG(Span(), "UfcsUnknown"); + ) + ) + ), + (Borrow, + os << "&"; + this->print_type(os, *e.inner); + ), + (Pointer, + os << "*"; + this->print_type(os, *e.inner); + ), + (Slice, + os << "["; + this->print_type(os, *e.inner); + os << "]"; + ), + (Array, + os << "["; + this->print_type(os, *e.inner); + os << "; " << e.size_val << "]"; + ), + (Closure, + //for(const auto& arg : e.m_arg_types) + // if( type_contains_ivars(arg) ) + // return true; + //return type_contains_ivars(*e.m_rettype); + ), + (Function, + //for(const auto& arg : e.m_arg_types) + // if( type_contains_ivars(arg) ) + // return true; + //return type_contains_ivars(*e.m_rettype); + ), + (TraitObject, + os << "(" << e.m_trait.m_path.m_path; + H::print_pp(*this, os, e.m_trait.m_path.m_params); + for(const auto& marker : e.m_markers) { + os << "+" << marker.m_path; + H::print_pp(*this, os, marker.m_params); + } + os << ")"; + ), + (Tuple, + os << "("; + for(const auto& st : e) { + this->print_type(os, st); + os << ","; + } + os << ")"; + ) + ) +} + /// /// Add inferrence variables to the provided type (if they're not already set) /// @@ -2141,7 +2253,7 @@ bool typeck::TypecheckContext::find_method(const Span& sp, const ::HIR::TypeRef& DEBUG("Search for impl of " << *trait_ref.first); // TODO: Need a "don't care" marker for the PathParams if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](const auto&,const auto&) { return true; }) ) { - DEBUG("Found trait impl " << *trait_ref.first << " for " << ty); + DEBUG("Found trait impl " << *trait_ref.first << " (" /*<< FmtType(*this, *trait_ref.first)*/ << ") for " << ty << " ("<<FmtType(*this, ty)<<")"); fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({ box$( ty.clone() ), trait_ref.first->clone(), |