diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-13 14:35:03 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-13 14:35:03 +0800 |
commit | 2505e79b6ed4942579bf2277470aa1e00dcd0053 (patch) | |
tree | d2bff886368716d1d5d82d0b951b9c3492e22a72 /src | |
parent | 2dd9abe0cd5e9c2b6f8235af697332e063efc9aa (diff) | |
download | mrust-2505e79b6ed4942579bf2277470aa1e00dcd0053.tar.gz |
HIR Typecheck - Handle generics when searching for BinOp impls
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr.cpp | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index 03276a9d..c152e2bd 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -906,6 +906,10 @@ namespace typeck { } assert(item_name); + //bool found = this->conext.find_trait_impls(sp, ops_trait, ops_trait_pp, ty_left,[&](const auto& args, const auto& assoc) { + // // TODO: Receive fuzzyness from `find_trait_impls` + // }); + // Search for ops trait impl const ::HIR::TraitImpl* impl_ptr = nullptr; ::HIR::TypeRef possible_right_type; @@ -943,17 +947,40 @@ namespace typeck { assert( impl.m_trait_args.m_types.size() == 1 ); const auto& arg_type = impl.m_trait_args.m_types[0]; - if( monomorphise_type_needed(arg_type) ) { - return true; - //TODO(node.span(), "Compare ops trait type when it contains generics - " << arg_type << " == " << ty_right); - } - auto cmp = arg_type.compare_with_placeholders(node.span(), ty_right, this->context.callback_resolve_infer()); - if( cmp == ::HIR::Compare::Unequal ) { + DEBUG("impl" << impl.m_params.fmt_args() << " " << ops_trait << impl.m_trait_args << " for " << impl.m_type); + + bool fail = false; + bool fuzzy = false; + ::std::vector< const ::HIR::TypeRef*> impl_params; + impl_params.resize( impl.m_params.m_types.size() ); + auto cb = [&](auto idx, const auto& ty) { + DEBUG("[_BinOp] " << idx << " = " << ty); + assert( idx < impl_params.size() ); + if( ! impl_params[idx] ) { + impl_params[idx] = &ty; + } + else { + switch( impl_params[idx]->compare_with_placeholders(node.span(), ty, this->context.callback_resolve_infer()) ) + { + case ::HIR::Compare::Unequal: + fail = true; + break; + case ::HIR::Compare::Fuzzy: + fuzzy = true; + break; + case ::HIR::Compare::Equal: + break; + } + } + }; + fail |= !impl.m_type.match_test_generics(sp, ty_left, this->context.callback_resolve_infer(), cb); + fail |= !arg_type.match_test_generics(sp, ty_right, this->context.callback_resolve_infer(), cb); + if( fail ) { return false; } count += 1; impl_ptr = &impl; - if( cmp == ::HIR::Compare::Equal ) { + if( !fuzzy ) { DEBUG("Operator impl exact match - '"<<item_name<<"' - " << arg_type << " == " << ty_right); return true; } |