summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/hir.cpp15
-rw-r--r--src/hir/type.cpp7
-rw-r--r--src/hir_typeck/helpers.cpp9
3 files changed, 24 insertions, 7 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 8f35ba0c..c2ad4d00 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -73,14 +73,21 @@ namespace {
}
throw "";
}
- if( right.m_data.is_Generic() ) {
- return left.m_data.is_Generic();
- }
+ // A local generic could match anything, leave that up to the caller
if( left.m_data.is_Generic() ) {
- // True? (TODO: Check bounds?)
return true;
}
+ // A local UfcsKnown can only be becuase it couldn't be expanded earlier, assume it could match
+ if( left.m_data.is_Path() && left.m_data.as_Path().path.m_data.is_UfcsKnown() ) {
+ // True?
+ return true;
+ }
+
+ // If the RHS (provided) is generic, it can only match if it binds to a local type parameter
+ if( right.m_data.is_Generic() ) {
+ return left.m_data.is_Generic();
+ }
if( left.m_data.tag() != right.m_data.tag() ) {
return false;
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 4c7a162f..de60dcb1 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -524,7 +524,14 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
break;
}
)
+
if( v.m_data.tag() != x.m_data.tag() ) {
+ // HACK: If the path is Opaque, return a fuzzy match.
+ // - This works around an impl selection bug.
+ if( v.m_data.is_Path() && v.m_data.as_Path().binding.is_Opaque() ) {
+ DEBUG("- Fuzzy match due to opaque");
+ return Compare::Fuzzy;
+ }
DEBUG("- Tag mismatch " << v << " and " << x);
return Compare::Unequal;
}
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index b44420fb..64a12801 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1880,7 +1880,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
) const
{
TRACE_FUNCTION_F(trait << FMT_CB(ss, if(params_ptr) { ss << *params_ptr; } else { ss << "<?>"; }) << " for " << type);
- // TODO: Parameter defaults - apply here or in the caller?
+
return this->m_crate.find_trait_impls(trait, type, this->m_ivars.callback_resolve_infer(),
[&](const auto& impl) {
DEBUG("[find_trait_impls_crate] Found impl" << impl.m_params.fmt_args() << " " << trait << impl.m_trait_args << " for " << impl.m_type << " " << impl.m_params.fmt_bounds());
@@ -1899,6 +1899,8 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
return impl_params[idx]->compare_with_placeholders(sp, ty, this->m_ivars.callback_resolve_infer());
}
};
+ // NOTE: If this type references an associated type, the match will incorrectly fail.
+ // - HACK: match_test_generics_fuzz has been changed to return Fuzzy if there's a tag mismatch and the LHS is an Opaque path
match &= impl.m_type.match_test_generics_fuzz(sp, type , this->m_ivars.callback_resolve_infer(), cb);
if( params_ptr )
{
@@ -1907,14 +1909,14 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
for(unsigned int i = 0; i < impl.m_trait_args.m_types.size(); i ++)
match &= impl.m_trait_args.m_types[i].match_test_generics_fuzz(sp, params.m_types[i], this->m_ivars.callback_resolve_infer(), cb);
if( match == ::HIR::Compare::Unequal ) {
- DEBUG("- Failed to match parameters - " << impl.m_trait_args << "+" << impl.m_type << " != " << params << "+" << type);
+ DEBUG("[find_trait_impls_crate] - Failed to match parameters - " << impl.m_trait_args << "+" << impl.m_type << " != " << params << "+" << type);
return false;
}
}
else
{
if( match == ::HIR::Compare::Unequal ) {
- DEBUG("- Failed to match type - " << impl.m_type << " != " << type);
+ DEBUG("[find_trait_impls_crate] - Failed to match type - " << impl.m_type << " != " << type);
return false;
}
}
@@ -1972,6 +1974,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
};
auto ty_mono = monomorphise_type_with(sp, impl.m_type, monomorph, false);
auto args_mono = monomorphise_path_params_with(sp, impl.m_trait_args, monomorph, false);
+ // TODO: Expand associated types in these then ensure that they still match the desired types.
// Check bounds for this impl
// - If a bound fails, then this can't be a valid impl