summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp50
-rw-r--r--src/hir_typeck/expr_simple.cpp2
-rw-r--r--src/hir_typeck/expr_simple.hpp6
-rw-r--r--src/hir_typeck/helpers.cpp19
-rw-r--r--src/hir_typeck/helpers.hpp4
5 files changed, 52 insertions, 29 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index cbb6ab9a..0ddeecad 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -37,6 +37,7 @@ struct Context
};
struct Associated
{
+ Span span;
::HIR::TypeRef left_ty;
::HIR::SimplePath trait;
@@ -1852,6 +1853,7 @@ void Context::equate_types_assoc(const Span& sp, const ::HIR::TypeRef& l, const
::HIR::PathParams pp;
pp.m_types = mv$(ty_args);
this->link_assoc.push_back(Associated {
+ sp,
l.clone(),
trait.clone(),
@@ -2203,21 +2205,26 @@ namespace {
bool check_associated(Context& context, const Context::Associated& v)
{
- TODO(Span(), "check_associated - " << v);
+ const auto& sp = v.span;
+
+ ::HIR::TypeRef possible_impl_ty;
+ ::HIR::PathParams possible_params;
- #if 0
// Search for ops trait impl
- const ::HIR::TraitImpl* impl_ptr = nullptr;
unsigned int count = 0;
- DEBUG("Searching for impl " << ops_trait << "< " << ty_right << "> for " << ty_left);
- bool found_bound = this->context.find_trait_impls_bound(sp, ops_trait, ops_trait_pp, ty_left,
- [&](const auto& args, const auto& assoc) {
- assert(args.m_types.size() == 1);
- const auto& arg_type = args.m_types[0];
- // TODO: if arg_type mentions Self?
- auto cmp = arg_type.compare_with_placeholders(node.span(), ty_right, this->context.callback_resolve_infer());
+ DEBUG("Searching for impl " << v.trait << v.params << " for " << v.impl_ty);
+ bool found = context.m_resolve.find_trait_impls(sp, v.trait, v.params, v.impl_ty,
+ [&](const auto& impl_ty, const auto& args, const auto& assoc) {
+ ::HIR::Compare cmp = impl_ty.compare_with_placeholders(sp, v.impl_ty, context.m_ivars.callback_resolve_infer());
+ assert( args.m_types.size() == v.params.m_types.size() );
+ for( unsigned int i = 0; i < args.m_types.size(); i ++ )
+ {
+ const auto& impl_ty = args.m_types[i];
+ const auto& rule_ty = v.params.m_types[i];
+ cmp &= impl_ty.compare_with_placeholders(sp, rule_ty, context.m_ivars.callback_resolve_infer());
+ }
if( cmp == ::HIR::Compare::Unequal ) {
- DEBUG("- (fail) bounded impl " << ops_trait << "<" << arg_type << "> (ty_right = " << this->context.get_type(ty_right));
+ DEBUG("- (fail) bounded impl " << v.trait << v.params << " (ty_right = " << context.m_ivars.fmt_type(v.impl_ty));
return false;
}
count += 1;
@@ -2225,14 +2232,29 @@ namespace {
return true;
}
else {
- if( possible_right_type == ::HIR::TypeRef() ) {
- DEBUG("- Set possibility for " << ty_right << " - " << arg_type);
- possible_right_type = arg_type.clone();
+ if( possible_impl_ty == ::HIR::TypeRef() ) {
+ possible_impl_ty = impl_ty.clone();
+ possible_params = args.clone();
}
return false;
}
});
+ if( found ) {
+ // Fully-known impl
+ }
+ else if( count == 0 ) {
+ // No applicable impl
+ }
+ else if( count == 1 ) {
+ // Only one possible impl
+ }
+ else {
+ // Multiple possible impls, don't know yet
+ }
+
+ TODO(sp, "check_associated - " << v);
+ #if 0
// - Only set found_exact if either found_bound returned true, XOR this returns true
bool found_exact = found_bound ^ this->context.m_crate.find_trait_impls(ops_trait, ty_left, this->context.callback_resolve_infer(),
[&](const auto& impl) {
diff --git a/src/hir_typeck/expr_simple.cpp b/src/hir_typeck/expr_simple.cpp
index a3012a99..ce3b0ef5 100644
--- a/src/hir_typeck/expr_simple.cpp
+++ b/src/hir_typeck/expr_simple.cpp
@@ -719,7 +719,6 @@ namespace typeck {
// });
// Search for ops trait impl
- const ::HIR::TraitImpl* impl_ptr = nullptr;
::HIR::TypeRef possible_right_type;
unsigned int count = 0;
const auto& ops_trait = this->context.m_crate.get_lang_item_path(node.span(), item_name);
@@ -750,6 +749,7 @@ namespace typeck {
}
});
// - Only set found_exact if either found_bound returned true, XOR this returns true
+ const ::HIR::TraitImpl* impl_ptr = nullptr;
bool found_exact = found_bound ^ this->context.m_crate.find_trait_impls(ops_trait, ty_left, this->context.callback_resolve_infer(),
[&](const auto& impl) {
assert( impl.m_trait_args.m_types.size() == 1 );
diff --git a/src/hir_typeck/expr_simple.hpp b/src/hir_typeck/expr_simple.hpp
index 1268918b..18cf966a 100644
--- a/src/hir_typeck/expr_simple.hpp
+++ b/src/hir_typeck/expr_simple.hpp
@@ -125,16 +125,16 @@ public:
/// Searches for a trait impl that matches the provided trait name and type
bool find_trait_impls(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const {
- return m_resolve.find_trait_impls(sp, trait, params, type, callback);
+ return m_resolve.find_trait_impls(sp, trait, params, type, [&](const auto& _, const auto& a, const auto& b){ return callback(a,b); });
}
/// Search for a trait implementation in current bounds
bool find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const {
- return m_resolve.find_trait_impls_bound(sp, trait, params, type, callback);
+ return m_resolve.find_trait_impls_bound(sp, trait, params, type, [&](const auto& _, const auto& a, const auto& b){ return callback(a,b); });
}
/// Search for a trait implementation in the crate
bool find_trait_impls_crate(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const {
- return m_resolve.find_trait_impls_crate(sp, trait, params, type, callback);
+ return m_resolve.find_trait_impls_crate(sp, trait, params, type, [&](const auto& _, const auto& a, const auto& b){ return callback(a,b); });
}
/// Locate the named method by applying auto-dereferencing.
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 03c38cb0..238b2cac 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -862,7 +862,7 @@ bool TraitResolution::find_trait_impls(const Span& sp,
pp.m_types.push_back( ::HIR::TypeRef(mv$(args)) );
::std::map< ::std::string, ::HIR::TypeRef> types;
types.insert( ::std::make_pair( "Output", e.m_rettype->clone() ) );
- return callback( pp, types );
+ return callback( type, pp, types );
}
else {
return false;
@@ -997,7 +997,7 @@ void TraitResolution::compact_ivars(HMTypeInferrence& m_ivars)
bool found_supertrait = this->find_named_trait_in_trait(sp,
e2.trait.m_path, e2.trait.m_params,
*be.trait.m_trait_ptr, be.trait.m_path.m_path, be.trait.m_path.m_params, *e2.type,
- [&e2,&input,&assume_opaque](const auto& x, const auto& assoc){
+ [&e2,&input,&assume_opaque](const auto&, const auto& x, const auto& assoc){
auto it = assoc.find(e2.item);
if( it != assoc.end() ) {
assume_opaque = false;
@@ -1131,7 +1131,7 @@ void TraitResolution::compact_ivars(HMTypeInferrence& m_ivars)
BUG(sp, "Cannot find associated type " << e2.item << " anywhere in trait " << e2.trait);
//e2.trait = mv$(trait_path);
- rv = this->find_trait_impls_crate(sp, trait_path.m_path, trait_path.m_params, *e2.type, [&](const auto& args, const auto& assoc) {
+ rv = this->find_trait_impls_crate(sp, trait_path.m_path, trait_path.m_params, *e2.type, [&](const auto& , const auto& args, const auto& assoc) {
DEBUG("Found impl for " << e2.trait.m_path << args << " with types {" << assoc << "}");
auto it = assoc.find( e2.item );
if( it == assoc.end() )
@@ -1221,7 +1221,7 @@ bool TraitResolution::find_named_trait_in_trait(const Span& sp,
DEBUG(pt << " => " << pt_mono);
if( pt.m_path.m_path == des ) {
- callback( pt_mono.m_path.m_params, pt_mono.m_type_bounds );
+ callback( target_type, pt_mono.m_path.m_params, pt_mono.m_type_bounds );
return true;
}
}
@@ -1255,7 +1255,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple
DEBUG("Fuzzy match");
}
// Hand off to the closure, and return true if it does
- if( callback(e.trait.m_path.m_params, e.trait.m_type_bounds) ) {
+ if( callback(e.type, e.trait.m_path.m_params, e.trait.m_type_bounds) ) {
return true;
}
}
@@ -1314,6 +1314,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
assert( ge.binding < impl_params.size() );
return *impl_params[ge.binding];
};
+ 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: Check bounds
@@ -1332,7 +1333,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
ab.second = this->expand_associated_types(sp, mv$(ab.second));
}
DEBUG("- " << real_type << " : " << real_trait);
- auto rv = this->find_trait_impls(sp, real_trait.m_path.m_path, real_trait.m_path.m_params, real_type, [&](const auto& a, const auto& t) {
+ auto rv = this->find_trait_impls(sp, real_trait.m_path.m_path, real_trait.m_path.m_params, real_type, [&](const auto&, const auto& a, const auto& t) {
for(const auto& assoc_bound : real_trait.m_type_bounds) {
auto it = t.find(assoc_bound.first);
if( it == t.end() )
@@ -1377,7 +1378,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
//if( match == ::HIR::Compare::Fuzzy ) {
// TODO(sp, "- Pass on fuzzy match status");
//}
- return callback(args_mono, types/*, (match == ::HIR::Compare::Fuzzy)*/);
+ return callback(ty_mono, args_mono, types/*, (match == ::HIR::Compare::Fuzzy)*/);
}
);
}
@@ -1451,7 +1452,7 @@ const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::Ty
return &tmp_type;
)
else {
- bool succ = this->find_trait_impls(sp, this->m_crate.get_lang_item_path(sp, "deref"), ::HIR::PathParams {}, ty, [&](const auto& args, const auto& types) {
+ bool succ = this->find_trait_impls(sp, this->m_crate.get_lang_item_path(sp, "deref"), ::HIR::PathParams {}, ty, [&](const auto&, const auto& args, const auto& types) {
assert(args.m_types.size() == 0);
// TODO: Use `types`
return true;
@@ -1620,7 +1621,7 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait
continue ;
DEBUG("Search for impl of " << *trait_ref.first);
// TODO: Need a "don't care" marker for the PathParams
- if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](const auto&,const auto&) { return true; }) ) {
+ if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](const auto&,const auto&,const auto&) { return true; }) ) {
DEBUG("Found trait impl " << *trait_ref.first << " (" /*<< m_ivars.fmt_type(*trait_ref.first)*/ << ") for " << ty << " ("<<m_ivars.fmt_type(ty)<<")");
fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({
box$( ty.clone() ),
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index ec33bd78..9c3a110b 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -128,8 +128,6 @@ public:
{
}
- typedef ::std::function<bool(const ::HIR::PathParams&, const ::std::map< ::std::string,::HIR::TypeRef>&)> t_cb_trait_impl;
-
void compact_ivars(HMTypeInferrence& m_ivars);
/// Check if a trait bound applies, using the passed function to expand Generic/Infer types
@@ -141,6 +139,8 @@ public:
/// Iterate over in-scope bounds (function then top)
bool iterate_bounds( ::std::function<bool(const ::HIR::GenericBound&)> cb) const;
+ typedef ::std::function<bool(const ::HIR::TypeRef&, const ::HIR::PathParams&, const ::std::map< ::std::string,::HIR::TypeRef>&)> t_cb_trait_impl;
+
/// Searches for a trait impl that matches the provided trait name and type
bool find_trait_impls(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const;