summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/type.cpp4
-rw-r--r--src/hir_typeck/helpers.cpp129
2 files changed, 103 insertions, 30 deletions
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 865607bc..fafbc670 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -1039,7 +1039,9 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
return rv;
),
(ErasedType,
- TODO(sp, "ErasedType");
+ auto rv = le.m_origin .compare_with_placeholders( sp, le.m_origin, resolve_placeholder );
+ return rv;
+ //TODO(sp, "ErasedType");
),
(Array,
if( le.size_val != re.size_val )
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 8eaf031c..a488fda4 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -800,40 +800,47 @@ bool HMTypeInferrence::types_equal(const ::HIR::TypeRef& rl, const ::HIR::TypeRe
if( l.m_data.tag() != r.m_data.tag() )
return false;
+ struct H {
+ static bool compare_path(const HMTypeInferrence& self, const ::HIR::Path& l, const ::HIR::Path& r) {
+ if( l.m_data.tag() != r.m_data.tag() )
+ return false;
+ TU_MATCH(::HIR::Path::Data, (l.m_data, r.m_data), (lpe, rpe),
+ (Generic,
+ if( lpe.m_path != rpe.m_path )
+ return false;
+ return self.pathparams_equal(lpe.m_params, rpe.m_params);
+ ),
+ (UfcsKnown,
+ if( lpe.item != rpe.item )
+ return false;
+ if( ! self.types_equal(*lpe.type, *rpe.type) )
+ return false;
+ if( ! self.pathparams_equal(lpe.trait.m_params, rpe.trait.m_params) )
+ return false;
+ return self.pathparams_equal(lpe.params, rpe.params);
+ ),
+ (UfcsInherent,
+ if( lpe.item != rpe.item )
+ return false;
+ if( ! self.types_equal(*lpe.type, *rpe.type) )
+ return false;
+ return self.pathparams_equal(lpe.params, rpe.params);
+ ),
+ (UfcsUnknown,
+ BUG(Span(), "UfcsUnknown");
+ )
+ )
+ throw "";
+ }
+ };
+
TU_MATCH(::HIR::TypeRef::Data, (l.m_data, r.m_data), (le, re),
(Infer, return le.index == re.index; ),
(Primitive, return le == re; ),
(Diverge, return true; ),
(Generic, return le.binding == re.binding; ),
(Path,
- if( le.path.m_data.tag() != re.path.m_data.tag() )
- return false;
- TU_MATCH(::HIR::Path::Data, (le.path.m_data, re.path.m_data), (lpe, rpe),
- (Generic,
- if( lpe.m_path != rpe.m_path )
- return false;
- return pathparams_equal(lpe.m_params, rpe.m_params);
- ),
- (UfcsKnown,
- if( lpe.item != rpe.item )
- return false;
- if( ! types_equal(*lpe.type, *rpe.type) )
- return false;
- if( ! pathparams_equal(lpe.trait.m_params, rpe.trait.m_params) )
- return false;
- return pathparams_equal(lpe.params, rpe.params);
- ),
- (UfcsInherent,
- if( lpe.item != rpe.item )
- return false;
- if( ! types_equal(*lpe.type, *rpe.type) )
- return false;
- return pathparams_equal(lpe.params, rpe.params);
- ),
- (UfcsUnknown,
- BUG(Span(), "UfcsUnknown");
- )
- )
+ return H::compare_path(*this, le.path, re.path);
),
(Borrow,
if( le.type != re.type )
@@ -879,7 +886,8 @@ bool HMTypeInferrence::types_equal(const ::HIR::TypeRef& rl, const ::HIR::TypeRe
return pathparams_equal(le.m_trait.m_path.m_params, re.m_trait.m_path.m_params);
),
(ErasedType,
- TODO(Span(), "ErasedType");
+ return H::compare_path(*this, le.m_origin, re.m_origin);
+ //TODO(Span(), "ErasedType");
),
(Tuple,
return type_list_equal(*this, le, re);
@@ -1780,6 +1788,69 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp,
}
)
+ // If it's a ErasedType, then maybe we're asking for a bound
+ TU_IFLET(::HIR::TypeRef::Data, pe.type->m_data, ErasedType, te,
+ for( const auto& trait : te.m_traits )
+ {
+ const auto& trait_gp = trait.m_path;
+ if( pe.trait.m_path == trait_gp.m_path ) {
+ auto cmp = ::HIR::Compare::Equal;
+ if( pe.trait.m_params.m_types.size() != trait_gp.m_params.m_types.size() )
+ {
+ cmp = ::HIR::Compare::Unequal;
+ }
+ else
+ {
+ for(unsigned int i = 0; i < pe.trait.m_params.m_types.size(); i ++)
+ {
+ const auto& l = pe.trait.m_params.m_types[i];
+ const auto& r = trait_gp.m_params.m_types[i];
+ cmp &= l.compare_with_placeholders(sp, r, m_ivars.callback_resolve_infer());
+ }
+ }
+ if( cmp != ::HIR::Compare::Unequal )
+ {
+ auto it = trait.m_type_bounds.find( pe.item );
+ if( it == trait.m_type_bounds.end() ) {
+ // TODO: Mark as opaque and return.
+ // - Why opaque? It's not bounded, don't even bother
+ TODO(sp, "Handle unconstrained associate type " << pe.item << " from " << *pe.type);
+ }
+
+ input = it->second.clone();
+ return ;
+ }
+ }
+
+ // - Check if the desired trait is a supertrait of this.
+ // NOTE: `params` (aka des_params) is not used (TODO)
+ bool is_supertrait = this->find_named_trait_in_trait(sp, pe.trait.m_path,pe.trait.m_params, *trait.m_trait_ptr, trait_gp.m_path,trait_gp.m_params, *pe.type,
+ [&](const auto& i_ty, const auto& i_params, const auto& i_assoc) {
+ // The above is just the monomorphised params and associated set. Comparison is still needed.
+ auto cmp = this->compare_pp(sp, i_params, pe.trait.m_params);
+ if( cmp != ::HIR::Compare::Unequal ) {
+ auto it = i_assoc.find( pe.item );
+ if( it != i_assoc.end() ) {
+ input = it->second.clone();
+ return true;
+ }
+ // NOTE: (currently) there can only be one trait with this name, so if we found this trait and the item is present - good.
+ it = trait.m_type_bounds.find( pe.item );
+ if( it != trait.m_type_bounds.end() ) {
+ input = it->second.clone();
+ return true;
+ }
+ return false;
+ }
+ return false;
+ });
+ if( is_supertrait )
+ {
+ return ;
+ }
+ }
+ )
+
// 1. Bounds
bool rv;
bool assume_opaque = true;