summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_expand/closures.cpp2
-rw-r--r--src/hir_typeck/expr_check.cpp2
-rw-r--r--src/hir_typeck/helpers.cpp6
-rw-r--r--src/hir_typeck/static.cpp93
-rw-r--r--src/hir_typeck/static.hpp20
5 files changed, 119 insertions, 4 deletions
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index f0f14b12..8fe46f0c 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -344,7 +344,7 @@ namespace {
// 2. Iterate over the nodes and rewrite variable accesses to either renumbered locals, or field accesses
- // - TODO: Monomorphise all referenced types within this
+ // - TODO: Monomorphise all referenced types within this.
ExprVisitor_Mutate ev { node.m_res_type, ent.local_vars, ent.node.m_var_captures };
ev.visit_node_ptr( node.m_code );
diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp
index a9668412..bbe028d0 100644
--- a/src/hir_typeck/expr_check.cpp
+++ b/src/hir_typeck/expr_check.cpp
@@ -948,7 +948,7 @@ namespace {
}
void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
{
- TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type);
+ TRACE_FUNCTION_F("impl" << impl.m_params.fmt_args() << " " << trait_path << " for " << impl.m_type);
auto _ = this->m_resolve.set_impl_generics(impl.m_params);
::HIR::Visitor::visit_trait_impl(trait_path, impl);
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 7792ed25..16b036f6 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -167,7 +167,11 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl)
}) );
),
(UfcsUnknown,
- TODO(sp, "UfcsUnknown - " << tpl);
+ rv = ::HIR::TypeRef( ::HIR::Path::Data::make_UfcsUnknown({
+ box$( monomorphise_type_with(sp, *e2.type, callback, allow_infer) ),
+ e2.item,
+ monomorphise_path_params_with(sp, e2.params, callback, allow_infer)
+ }) );
),
(UfcsInherent,
TODO(sp, "UfcsInherent - " << tpl);
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index 381405cf..9f56527e 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -7,6 +7,80 @@
*/
#include "static.hpp"
+void StaticTraitResolve::prep_indexes()
+{
+ static Span sp_AAA;
+ const Span& sp = sp_AAA;
+
+ TRACE_FUNCTION_F("");
+
+ auto add_equality = [&](::HIR::TypeRef long_ty, ::HIR::TypeRef short_ty){
+ DEBUG("[prep_indexes] ADD " << long_ty << " => " << short_ty);
+ // TODO: Sort the two types by "complexity" (most of the time long >= short)
+ this->m_type_equalities.insert(::std::make_pair( mv$(long_ty), mv$(short_ty) ));
+ };
+
+ this->iterate_bounds([&](const auto& b) {
+ TU_MATCH_DEF(::HIR::GenericBound, (b), (be),
+ (
+ ),
+ (TraitBound,
+ DEBUG("[prep_indexes] `" << be.type << " : " << be.trait);
+ for( const auto& tb : be.trait.m_type_bounds ) {
+ DEBUG("[prep_indexes] 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 ) );
+ ty_l.m_data.as_Path().binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
+
+ add_equality( mv$(ty_l), tb.second.clone() );
+ }
+
+ const auto& trait_params = be.trait.m_path.m_params;
+ auto cb_mono = [&](const auto& ty)->const auto& {
+ const auto& ge = ty.m_data.as_Generic();
+ if( ge.binding == 0xFFFF ) {
+ return be.type;
+ }
+ else if( ge.binding < 256 ) {
+ unsigned idx = ge.binding % 256;
+ ASSERT_BUG(sp, idx < trait_params.m_types.size(), "Generic binding out of range in trait " << be.trait);
+ return trait_params.m_types[idx];
+ }
+ else {
+ BUG(sp, "Unknown generic binding " << ty);
+ }
+ };
+
+ const auto& trait = m_crate.get_trait_by_path(sp, be.trait.m_path.m_path);
+ for(const auto& a_ty : trait.m_types)
+ {
+ ::HIR::TypeRef ty_a;
+ for( const auto& a_ty_b : a_ty.second.m_trait_bounds ) {
+ DEBUG("[prep_indexes] (Assoc) " << a_ty_b);
+ auto trait_mono = monomorphise_traitpath_with(sp, a_ty_b, cb_mono, false);
+ for( auto& tb : trait_mono.m_type_bounds ) {
+ if( ty_a == ::HIR::TypeRef() ) {
+ ty_a = ::HIR::TypeRef( ::HIR::Path( be.type.clone(), be.trait.m_path.clone(), a_ty.first ) );
+ ty_a.m_data.as_Path().binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
+ }
+ DEBUG("[prep_indexes] Equality (ATB) - <" << ty_a << " as " << a_ty_b.m_path << ">::" << tb.first << " = " << tb.second);
+
+ auto ty_l = ::HIR::TypeRef( ::HIR::Path( ty_a.clone(), trait_mono.m_path.clone(), tb.first ) );
+ ty_l.m_data.as_Path().binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
+
+ add_equality( mv$(ty_l), mv$(tb.second) );
+ }
+ }
+ }
+ ),
+ (TypeEquality,
+ DEBUG("Equality - " << be.type << " = " << be.other_type);
+ add_equality( be.type.clone(), be.other_type.clone() );
+ )
+ )
+ return false;
+ });
+}
+
bool StaticTraitResolve::find_impl(
const Span& sp,
const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params,
@@ -220,6 +294,9 @@ bool StaticTraitResolve::find_impl__check_crate(
DEBUG("[find_impl] Trait bound " << e.type << " : " << e.trait);
auto b_ty_mono = monomorphise_type_with(sp, e.type, cb_monomorph);
auto b_tp_mono = monomorphise_traitpath_with(sp, e.trait, cb_monomorph, false);
+ for(auto& ty : b_tp_mono.m_path.m_params.m_types) {
+ this->expand_associated_types(sp, ty);
+ }
for(auto& assoc_bound : b_tp_mono.m_type_bounds) {
// TODO: These should be tagged with the source trait and that source trait used for expansion.
this->expand_associated_types(sp, assoc_bound.second);
@@ -242,6 +319,7 @@ bool StaticTraitResolve::find_impl__check_crate(
auto rv = this->find_impl(sp, aty_src_trait.m_path, aty_src_trait.m_params, b_ty_mono, [&](const auto& impl) {
::HIR::TypeRef have = impl.get_type(aty_name.c_str());
+
//auto cmp = have .match_test_generics_fuzz(sp, exp, cb_ident, cb_match);
auto cmp = exp .match_test_generics_fuzz(sp, have, cb_ident, cb_match);
ASSERT_BUG(sp, cmp == ::HIR::Compare::Equal, "Assoc ty " << aty_name << " mismatch, " << have << " != des " << exp);
@@ -410,6 +488,8 @@ void StaticTraitResolve::expand_associated_types(const Span& sp, ::HIR::TypeRef&
if( assume_opaque ) {
input.m_data.as_Path().binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
DEBUG("Assuming that " << input << " is an opaque name");
+
+ this->replace_equalities(input);
}
this->expand_associated_types(sp, input);
return;
@@ -484,6 +564,7 @@ void StaticTraitResolve::expand_associated_types(const Span& sp, ::HIR::TypeRef&
// - If the trait contains any of the above, it's unknowable
// - Otherwise, it's an error
e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
+ this->replace_equalities(input);
DEBUG("Couldn't resolve associated type for " << input << " (and won't ever be able to, assuming opaque)");
),
(UfcsUnknown,
@@ -522,6 +603,18 @@ void StaticTraitResolve::expand_associated_types(const Span& sp, ::HIR::TypeRef&
)
}
+void StaticTraitResolve::replace_equalities(::HIR::TypeRef& input) const
+{
+ TRACE_FUNCTION_F("input="<<input);
+ DEBUG("m_type_equalities = {" << m_type_equalities << "}");
+ // - Check if there's an alias for this opaque name
+ auto a = m_type_equalities.find(input);
+ if( a != m_type_equalities.end() ) {
+ input = a->second.clone();
+ DEBUG("- Replace with " << input);
+ }
+}
+
// -------------------------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------------------------
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index 69eb2ba3..31ca1870 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -18,13 +18,22 @@ public:
::HIR::GenericParams* m_impl_generics;
::HIR::GenericParams* m_item_generics;
+
+
+ ::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities;
public:
StaticTraitResolve(const ::HIR::Crate& crate):
m_crate(crate),
m_impl_generics(nullptr),
m_item_generics(nullptr)
- {}
+ {
+ prep_indexes();
+ }
+
+private:
+ void prep_indexes();
+public:
const ::HIR::GenericParams& impl_generics() const {
static ::HIR::GenericParams empty;
return m_impl_generics ? *m_impl_generics : empty;
@@ -50,11 +59,15 @@ public:
NullOnDrop< ::HIR::GenericParams> set_impl_generics(::HIR::GenericParams& gps) {
assert( !m_impl_generics );
m_impl_generics = &gps;
+ m_type_equalities.clear();
+ prep_indexes();
return NullOnDrop< ::HIR::GenericParams>(m_impl_generics);
}
NullOnDrop< ::HIR::GenericParams> set_item_generics(::HIR::GenericParams& gps) {
assert( !m_item_generics );
m_item_generics = &gps;
+ m_type_equalities.clear();
+ prep_indexes();
return NullOnDrop< ::HIR::GenericParams>(m_item_generics);
}
/// \}
@@ -91,6 +104,11 @@ private:
public:
void expand_associated_types(const Span& sp, ::HIR::TypeRef& input) const;
+
+private:
+ void replace_equalities(::HIR::TypeRef& input) const;
+
+public:
/// \}
/// Iterate over in-scope bounds (function then top)