summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp27
-rw-r--r--src/hir/path.hpp25
-rw-r--r--src/hir/type.cpp88
-rw-r--r--src/hir/type.hpp2
-rw-r--r--src/hir_typeck/helpers.cpp29
-rw-r--r--src/hir_typeck/helpers.hpp5
6 files changed, 173 insertions, 3 deletions
diff --git a/src/common.hpp b/src/common.hpp
index 6dfcd495..7f7dbcb7 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -59,6 +59,15 @@ static inline Ordering ord(unsigned l, unsigned r)
else
return OrdLess;
}
+static inline Ordering ord(::std::uintptr_t l, ::std::uintptr_t r)
+{
+ if(l == r)
+ return OrdEqual;
+ else if( l > r )
+ return OrdGreater;
+ else
+ return OrdLess;
+}
static inline Ordering ord(const ::std::string& l, const ::std::string& r)
{
if(l == r)
@@ -97,9 +106,25 @@ Ordering ord(const ::std::vector<T>& l, const ::std::vector<T>& r)
i ++;
}
-
+
+ return OrdEqual;
+}
+template<typename T, typename U>
+Ordering ord(const ::std::map<T,U>& l, const ::std::map<T,U>& r)
+{
+ auto r_it = r.begin();
+ for(const auto& le : l)
+ {
+ if( r_it == r.end() )
+ return OrdGreater;
+ auto rv = ::ord( le, *r_it );
+ if( rv != OrdEqual )
+ return rv;
+ ++ r_it;
+ }
return OrdEqual;
}
+#define ORD(a,b) do { Ordering ORD_rv = ::ord(a,b); if( ORD_rv != ::OrdEqual ) return ORD_rv; } while(0)
template <typename T>
diff --git a/src/hir/path.hpp b/src/hir/path.hpp
index 59b5f111..cace3ff9 100644
--- a/src/hir/path.hpp
+++ b/src/hir/path.hpp
@@ -68,6 +68,12 @@ struct SimplePath
if( m_components < x.m_components ) return true;
return false;
}
+ Ordering ord(const SimplePath& x) const {
+ auto rv = ::ord(m_crate_name, x.m_crate_name);
+ if(rv != OrdEqual) return rv;
+ rv = ::ord(m_components, x.m_components);
+ return rv;
+ }
friend ::std::ostream& operator<<(::std::ostream& os, const SimplePath& x);
};
@@ -84,7 +90,10 @@ struct PathParams
PathParams& operator=(PathParams&&) = default;
bool operator==(const PathParams& x) const;
- //bool operator<(const PathParams& x) const;
+ bool operator<(const PathParams& x) const { return ord(x) == OrdLess; }
+ Ordering ord(const PathParams& x) const {
+ return ::ord(m_types, x.m_types);
+ }
friend ::std::ostream& operator<<(::std::ostream& os, const PathParams& x);
};
@@ -104,7 +113,13 @@ public:
bool operator==(const GenericPath& x) const;
bool operator!=(const GenericPath& x) const { return !(*this == x); }
- //bool operator<(const GenericPath& x) const;
+ bool operator<(const GenericPath& x) const { return ord(x) == OrdLess; }
+
+ Ordering ord(const GenericPath& x) const {
+ auto rv = ::ord(m_path, x.m_path);
+ if(rv != OrdEqual) return rv;
+ return ::ord(m_params, x.m_params);
+ }
friend ::std::ostream& operator<<(::std::ostream& os, const GenericPath& x);
};
@@ -123,6 +138,12 @@ public:
bool operator==(const TraitPath& x) const;
bool operator!=(const TraitPath& x) const { return !(*this == x); }
+ Ordering ord(const TraitPath& x) const {
+ ORD(m_path, x.m_path);
+ ORD(m_hrls, x.m_hrls);
+ return ::ord(m_type_bounds, x.m_type_bounds);
+ }
+
friend ::std::ostream& operator<<(::std::ostream& os, const TraitPath& x);
};
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 14fa4c46..7695f066 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -263,6 +263,94 @@ bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const
)
throw "";
}
+Ordering HIR::TypeRef::ord(const ::HIR::TypeRef& x) const
+{
+ Ordering rv;
+
+ ORD( static_cast<unsigned int>(m_data.tag()), static_cast<unsigned int>(x.m_data.tag()) );
+
+ TU_MATCH(::HIR::TypeRef::Data, (m_data, x.m_data), (te, xe),
+ (Infer,
+ // TODO: Should comparing inferrence vars be an error?
+ return ::ord( te.index, xe.index );
+ ),
+ (Diverge,
+ return OrdEqual;
+ ),
+ (Primitive,
+ return ::ord( static_cast<unsigned>(te), static_cast<unsigned>(xe) );
+ ),
+ (Path,
+ ORD( (unsigned)te.path.m_data.tag(), (unsigned)xe.path.m_data.tag() );
+ TU_MATCH(::HIR::Path::Data, (te.path.m_data, xe.path.m_data), (tpe, xpe),
+ (Generic,
+ return ::ord(tpe, xpe);
+ ),
+ (UfcsInherent,
+ ORD(*tpe.type, *xpe.type);
+ ORD(tpe.item, xpe.item);
+ return ::ord(tpe.params, xpe.params);
+ ),
+ (UfcsKnown,
+ ORD(*tpe.type, *xpe.type);
+ ORD(tpe.trait, xpe.trait);
+ ORD(tpe.item, xpe.item);
+ return ::ord(tpe.params, xpe.params);
+ ),
+ (UfcsUnknown,
+ ORD(*tpe.type, *xpe.type);
+ ORD(tpe.item, xpe.item);
+ return ::ord(tpe.params, xpe.params);
+ )
+ )
+ ),
+ (Generic,
+ ORD(te.name, xe.name);
+ if( (rv = ::ord(te.binding, xe.binding)) != OrdEqual )
+ return rv;
+ return OrdEqual;
+ ),
+ (TraitObject,
+ ORD(te.m_trait, xe.m_trait);
+ ORD(te.m_markers, xe.m_markers);
+ return OrdEqual;
+ //return ::ord(te.m_lifetime, xe.m_lifetime);
+ ),
+ (Array,
+ ORD(*te.inner, *xe.inner);
+ ORD(te.size_val, xe.size_val);
+ if( te.size_val == ~0u )
+ assert(!"TOD: Compre array types with non-resolved sizes");
+ return OrdEqual;
+ ),
+ (Slice,
+ return ::ord(*te.inner, *xe.inner);
+ ),
+ (Tuple,
+ return ::ord(te, xe);
+ ),
+ (Borrow,
+ ORD( static_cast<unsigned>(te.type), static_cast<unsigned>(xe.type) );
+ return ::ord(*te.inner, *xe.inner);
+ ),
+ (Pointer,
+ ORD( static_cast<unsigned>(te.type), static_cast<unsigned>(xe.type) );
+ return ::ord(*te.inner, *xe.inner);
+ ),
+ (Function,
+ ORD(te.is_unsafe, xe.is_unsafe);
+ ORD(te.m_abi, xe.m_abi);
+ ORD(te.m_arg_types, xe.m_arg_types);
+ return ::ord(*te.m_rettype, *xe.m_rettype);
+ ),
+ (Closure,
+ ORD( (::std::uintptr_t)te.node, xe.node);
+ //assert( te.m_rettype == xe.m_rettype );
+ return OrdEqual;
+ )
+ )
+ throw "";
+}
namespace {
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index f75a4d51..c5d08c5f 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -219,6 +219,8 @@ public:
bool operator==(const ::HIR::TypeRef& x) const;
bool operator!=(const ::HIR::TypeRef& x) const { return !(*this == x); }
+ bool operator<(const ::HIR::TypeRef& x) const { return ord(x) == OrdLess; }
+ Ordering ord(const ::HIR::TypeRef& x) const;
// Match generics in `this` with types from `x`
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index a66a6f84..fd5533e4 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -940,6 +940,28 @@ bool HMTypeInferrence::types_equal(const ::HIR::TypeRef& rl, const ::HIR::TypeRe
// -------------------------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------------------------
+void TraitResolution::prep_indexes()
+{
+ this->iterate_bounds([&](const auto& b) {
+ TU_MATCH_DEF(::HIR::GenericBound, (b), (be),
+ (
+ ),
+ (TraitBound,
+ for( const auto& tb : be.trait.m_type_bounds ) {
+ DEBUG("Equality (TB) - <" << be.type << " as " << be.trait.m_path << ">::" << tb.first << " = " << tb.second);
+ auto ty_l = ::HIR::TypeRef( ::HIR::Path( be.type.clone(), be.trait.m_path.clone(), tb.first ) );
+ this->m_type_equalities.insert( ::std::make_pair( mv$(ty_l), tb.second.clone() ) );
+ }
+ ),
+ (TypeEquality,
+ DEBUG("Equality - " << be.type << " = " << be.other_type);
+ // TODO: Sort the two types by "complexity"
+ this->m_type_equalities.insert( ::std::make_pair( be.type.clone(), be.other_type.clone() ) );
+ )
+ )
+ return false;
+ });
+}
// -------------------------------------------------------------------------------------------------------------------
@@ -1095,6 +1117,7 @@ bool TraitResolution::find_trait_impls(const Span& sp,
// -------------------------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------------------------
+
void TraitResolution::compact_ivars(HMTypeInferrence& m_ivars)
{
//m_ivars.compact_ivars([&](const ::HIR::TypeRef& t)->auto{ return this->expand_associated_types(Span(), t.clone); });
@@ -1250,6 +1273,7 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const
// - Only try resolving if the binding isn't known
if( !e.binding.is_Unbound() )
return input;
+ // TODO: If opaque, still search a list of known equalities
DEBUG("Locating associated type for " << e.path);
@@ -1337,6 +1361,7 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const
(TypeEquality,
DEBUG("Equality - " << be.type << " = " << be.other_type);
if( input == be.type ) {
+ assume_opaque = false;
input = be.other_type.clone();
return true;
}
@@ -1348,6 +1373,10 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const
if( assume_opaque ) {
DEBUG("Assuming that " << input << " is an opaque name");
input.m_data.as_Path().binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
+
+ DEBUG("- " << m_type_equalities.size() << " replacements");
+ for( const auto& v : m_type_equalities )
+ DEBUG(" > " << v.first << " = " << v.second);
}
input = this->expand_associated_types(sp, mv$(input));
return input;
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index cdcbc12c..2e55978e 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -144,6 +144,8 @@ class TraitResolution
const ::HIR::GenericParams* m_impl_params;
const ::HIR::GenericParams* m_item_params;
+ ::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities;
+
public:
TraitResolution(const HMTypeInferrence& ivars, const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params):
m_ivars(ivars),
@@ -151,8 +153,11 @@ public:
m_impl_params( impl_params ),
m_item_params( item_params )
{
+ prep_indexes();
}
+ void prep_indexes();
+
void compact_ivars(HMTypeInferrence& m_ivars);
/// Check if a trait bound applies, using the passed function to expand Generic/Infer types