summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-21 11:33:01 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-21 11:33:01 +0800
commit043650929718d9a66fe598be7d475d213f69fdff (patch)
treeb6448bd78f0c1c92aef9b66302d510cc77ed2b01 /src
parenta061ecdaa886886977939d844a70303dba81bc9c (diff)
downloadmrust-043650929718d9a66fe598be7d475d213f69fdff.tar.gz
HIR Typecheck Expr - Defer method selection until the signature can be known
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 50009d7c..222e55df 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -145,11 +145,12 @@ static void fix_param_count(const Span& sp, Context& context, const ::HIR::Gener
namespace {
- void visit_call_populate_cache_UfcsInherent(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache, const ::HIR::Function*& fcn_ptr);
+ bool visit_call_populate_cache(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache) __attribute__((warn_unused_result));
+ bool visit_call_populate_cache_UfcsInherent(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache, const ::HIR::Function*& fcn_ptr);
/// (HELPER) Populate the cache for nodes that use visit_call
/// TODO: If the function has multiple mismatched options, tell the caller to try again later?
- void visit_call_populate_cache(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache)
+ bool visit_call_populate_cache(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache)
{
TRACE_FUNCTION_FR(path, path);
assert(cache.m_arg_types.size() == 0);
@@ -232,7 +233,9 @@ namespace {
),
(UfcsInherent,
// NOTE: This case is kinda long, so it's refactored out into a helper
- visit_call_populate_cache_UfcsInherent(context, sp, path, cache, fcn_ptr);
+ if( !visit_call_populate_cache_UfcsInherent(context, sp, path, cache, fcn_ptr) ) {
+ return false;
+ }
)
)
@@ -295,8 +298,10 @@ namespace {
)
)
}
+
+ return true;
}
- void visit_call_populate_cache_UfcsInherent(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache, const ::HIR::Function*& fcn_ptr)
+ bool visit_call_populate_cache_UfcsInherent(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache, const ::HIR::Function*& fcn_ptr)
{
auto& e = path.m_data.as_UfcsInherent();
@@ -318,8 +323,8 @@ namespace {
ERROR(sp, E0000, "Failed to locate function " << path);
}
if( count > 1 ) {
- // TODO: Return a status to the caller so it can try in a later pass
- TODO(sp, "Multiple associated functions for " << path);
+ // Return a status to the caller so it can try again when there may be more information
+ return false;
}
assert(impl_ptr);
DEBUG("Found impl" << impl_ptr->m_params.fmt_args() << " " << impl_ptr->m_type);
@@ -414,6 +419,8 @@ namespace {
BUG(sp, "Generic bounding out of total range - " << ge.binding);
}
};
+
+ return true;
}
// -----------------------------------------------------------------------
@@ -1054,7 +1061,9 @@ namespace {
// Populate cache
{
- visit_call_populate_cache(this->context, node.span(), node.m_path, node.m_cache);
+ if( !visit_call_populate_cache(this->context, node.span(), node.m_path, node.m_cache) ) {
+ TODO(node.span(), "Emit revisit when _CallPath is ambiguous - " << node.m_path);
+ }
assert( node.m_cache.m_arg_types.size() >= 1);
if( node.m_args.size() != node.m_cache.m_arg_types.size() - 1 ) {
@@ -2033,7 +2042,10 @@ namespace {
//fix_param_count(sp, this->context, node.m_method_path, fcn.m_params, e.params);
)
)
- visit_call_populate_cache(this->context, node.span(), node.m_method_path, node.m_cache);
+ if( !visit_call_populate_cache(this->context, node.span(), node.m_method_path, node.m_cache) ) {
+ DEBUG("- AMBIGUOUS - Trying again later");
+ return ;
+ }
DEBUG("> m_method_path = " << node.m_method_path);
assert( node.m_cache.m_arg_types.size() >= 1);