diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-29 16:41:24 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-29 16:41:24 +0800 |
commit | e6b1c6b14d80d98af74d631521c246c61b5f3367 (patch) | |
tree | 7bbd1ec7fe17528b34389ac65b3d0c647678dd38 /src | |
parent | 3a31e6b5f85436d9b239e23cfcb6bf39e5ad052d (diff) | |
download | mrust-e6b1c6b14d80d98af74d631521c246c61b5f3367.tar.gz |
HIR Typecheck Expr - Autoderef library containers too
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 9dca74e7..b0d72e52 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2024,13 +2024,33 @@ namespace { const auto& ty_o = this->context.get_type(node.m_value->m_res_type); TRACE_FUNCTION_F("CallValue: ty=" << ty_o); + if( ty_o.m_data.is_Infer() ) { + // - Don't even bother + return ; + } + + // 1. Create a param set with a single tuple (of all argument types) + ::HIR::PathParams trait_pp; + { + ::std::vector< ::HIR::TypeRef> arg_types; + for(const auto& arg : node.m_args) { + arg_types.push_back( this->context.get_type(arg->m_res_type).clone() ); + } + trait_pp.m_types.push_back( ::HIR::TypeRef( mv$(arg_types) ) ); + } + unsigned int deref_count = 0; - bool keep_deref = false; + ::HIR::TypeRef tmp_type; // for autoderef const auto* ty_p = &ty_o; - do + + bool keep_looping = false; + do // } while( keep_looping ); { - keep_deref = false; + // Reset at the start of each loop + keep_looping = false; + const auto& ty = *ty_p; + DEBUG("- ty = " << ty); TU_MATCH_DEF(decltype(ty.m_data), (ty.m_data), (e), ( // Search for FnOnce impl @@ -2041,16 +2061,6 @@ namespace { ::HIR::TypeRef fcn_args_tup; ::HIR::TypeRef fcn_ret; - // 1. Create a param set with a single tuple (of all argument types) - ::HIR::PathParams trait_pp; - { - ::std::vector< ::HIR::TypeRef> arg_types; - for(const auto& arg : node.m_args) { - arg_types.push_back( this->context.get_type(arg->m_res_type).clone() ); - } - trait_pp.m_types.push_back( ::HIR::TypeRef( mv$(arg_types) ) ); - } - // 2. Locate an impl of FnOnce (exists for all other Fn* traits) auto was_bounded = this->context.m_resolve.find_trait_impls_bound(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp) { auto tup = impl.get_trait_ty_param(0); @@ -2099,23 +2109,35 @@ namespace { else TU_IFLET( ::HIR::TypeRef::Data, ty.m_data, Borrow, e, deref_count ++; ty_p = &this->context.get_type(*e.inner); - keep_deref = true; + DEBUG("Deref " << ty << " -> " << *ty_p); + keep_looping = true; continue ; ) - else if( !ty.m_data.is_Generic() ) - { - bool found = this->context.m_resolve.find_trait_impls_crate(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp) { - TODO(node.span(), "Use impl of FnOnce - " << impl); - return false; - }); - if( found ) { - } - TODO(node.span(), "Search crate for implementations of FnOnce for " << ty); - } else { + if( !ty.m_data.is_Generic() ) + { + bool found = this->context.m_resolve.find_trait_impls_crate(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp) { + TODO(node.span(), "Use impl of FnOnce - " << impl << " matching " << this->context.m_ivars.fmt_type(ty)); + return false; + }); + if( found ) { + // TODO: Fill cache. + TODO(node.span(), "Use found impl of FnOnce"); + break ; // leaves TU_MATCH + } + } + if( const auto* next_ty_p = this->context.m_resolve.autoderef(node.span(), ty, tmp_type) ) + { + DEBUG("Deref (autoderef) " << ty << " -> " << *next_ty_p); + deref_count ++; + ty_p = next_ty_p; + keep_looping = true; + continue ; + } + // Didn't find anything. Error? - ERROR(node.span(), E0000, "Unable to find an implementation of Fn* for " << ty); + ERROR(node.span(), E0000, "Unable to find an implementation of Fn* for " << this->context.m_ivars.fmt_type(ty)); } node.m_arg_types = mv$( fcn_args_tup.m_data.as_Tuple() ); @@ -2138,7 +2160,7 @@ namespace { return ; ) ) - } while( keep_deref ); + } while( keep_looping ); if( deref_count > 0 ) { |