summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/hir.cpp64
-rw-r--r--src/hir_typeck/expr.hpp2
-rw-r--r--src/hir_typeck/expr_context.cpp114
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(),