diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 50 | ||||
-rw-r--r-- | src/hir_typeck/expr_simple.cpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_simple.hpp | 6 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 19 | ||||
-rw-r--r-- | src/hir_typeck/helpers.hpp | 4 |
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; |