summaryrefslogtreecommitdiff
path: root/src/hir_typeck
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-08-23 22:40:56 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-08-23 22:40:56 +0800
commit2e3867a4ccf00df8974ae1158dd73f269063b112 (patch)
treee40656b47546ae56ccfa00bbdbffa508d52112f3 /src/hir_typeck
parent185959964b6f1e9f1b67d4eb8b2d1932096e2de2 (diff)
downloadmrust-2e3867a4ccf00df8974ae1158dd73f269063b112.tar.gz
HIR Typecheck - Specialiation deep overlap checks, little impl param determining fix
Diffstat (limited to 'src/hir_typeck')
-rw-r--r--src/hir_typeck/expr_cs.cpp17
-rw-r--r--src/hir_typeck/impl_ref.cpp4
-rw-r--r--src/hir_typeck/impl_ref.hpp3
3 files changed, 18 insertions, 6 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index d613ad1e..6d91b698 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1710,13 +1710,21 @@ namespace {
// If the impl block has parameters, figure out what types they map to
// - The function params are already mapped (from fix_param_count)
auto& impl_params = e.impl_params;
- if( impl_ptr->m_params.m_types.size() > 0 ) {
+ if( impl_ptr->m_params.m_types.size() > 0 )
+ {
impl_params.m_types.resize( impl_ptr->m_params.m_types.size() );
- impl_ptr->m_type.match_generics(sp, *e.type, this->context.m_ivars.callback_resolve_infer(), [&](auto idx, const auto& ty) {
+ // NOTE: Could be fuzzy.
+ bool r = impl_ptr->m_type.match_test_generics(sp, *e.type, this->context.m_ivars.callback_resolve_infer(), [&](auto idx, const auto& ty) {
assert( idx < impl_params.m_types.size() );
impl_params.m_types[idx] = ty.clone();
return ::HIR::Compare::Equal;
});
+ if(!r)
+ {
+ auto cb = monomorphise_type_get_cb(sp, nullptr, &impl_params, nullptr);
+ auto t = monomorphise_type_with(sp, impl_ptr->m_type, cb);
+ this->context.equate_types(node.span(), t, *e.type);
+ }
for(const auto& ty : impl_params.m_types)
assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) );
}
@@ -4943,6 +4951,7 @@ namespace {
context.equate_types_from_shadow(sp, v.left_ty);
}
+#if 0
// HACK! If the trait is `Unsize` then pretend `impl<T> Unsize<T> for T` exists to possibly propagate the type through
// - Also applies to CoerceUnsized (which may not get its impl detected because actually `T: !Unsize<T>`)
// - This is needed because `check_coerce` will emit coercions where they're not actually needed in some cases.
@@ -5056,6 +5065,7 @@ namespace {
DEBUG("Found at least one impl of CoerceUnsized, running expensive code");
}
}
+#endif
// Locate applicable trait impl
unsigned int count = 0;
@@ -5112,7 +5122,7 @@ namespace {
// - If more specific, replace. If less, ignore.
#if 1
// NOTE: `overlaps_with` (should be) reflective
- else if( impl.overlaps_with(best_impl) )
+ else if( impl.overlaps_with(context.m_crate, best_impl) )
{
DEBUG("[check_associated] - Overlaps with existing - " << best_impl);
// if not more specific than the existing best, ignore.
@@ -5149,6 +5159,7 @@ namespace {
});
if( found ) {
// Fully-known impl
+ DEBUG("Fully-known impl located");
if( v.name != "" ) {
// Stop this from just pushing the same rule again.
if( output_type.m_data.is_Path() && output_type.m_data.as_Path().path.m_data.is_UfcsKnown() )
diff --git a/src/hir_typeck/impl_ref.cpp b/src/hir_typeck/impl_ref.cpp
index d3cfd215..e8966b38 100644
--- a/src/hir_typeck/impl_ref.cpp
+++ b/src/hir_typeck/impl_ref.cpp
@@ -40,14 +40,14 @@ bool ImplRef::more_specific_than(const ImplRef& other) const
)
throw "";
}
-bool ImplRef::overlaps_with(const ImplRef& other) const
+bool ImplRef::overlaps_with(const ::HIR::Crate& crate, const ImplRef& other) const
{
if( this->m_data.tag() != other.m_data.tag() )
return false;
TU_MATCH(Data, (this->m_data, other.m_data), (te, oe),
(TraitImpl,
if( te.impl != nullptr && oe.impl != nullptr )
- return te.impl->overlaps_with( *oe.impl );
+ return te.impl->overlaps_with( crate, *oe.impl );
),
(BoundedPtr,
),
diff --git a/src/hir_typeck/impl_ref.hpp b/src/hir_typeck/impl_ref.hpp
index ba747346..126daeda 100644
--- a/src/hir_typeck/impl_ref.hpp
+++ b/src/hir_typeck/impl_ref.hpp
@@ -3,6 +3,7 @@
#pragma once
#include <hir/type.hpp>
+#include <hir/hir.hpp>
namespace HIR {
class TraitImpl;
@@ -51,7 +52,7 @@ struct ImplRef
}
bool more_specific_than(const ImplRef& other) const;
- bool overlaps_with(const ImplRef& other) const;
+ bool overlaps_with(const ::HIR::Crate& crate, const ImplRef& other) const;
bool has_magic_params() const {
TU_IFLET(Data, m_data, TraitImpl, e,