summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-29 17:08:35 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-29 17:08:35 +0800
commiteb35918cbc7aa686e5b97d28787ccdfd412926de (patch)
tree5c5df5546dc0fc02f7348baaf586aef21f87331c /src
parentc7d8b6ac728cf3a27e0432a4b0b93584298f4eb0 (diff)
downloadmrust-eb35918cbc7aa686e5b97d28787ccdfd412926de.tar.gz
HIR Typecheck Expr - Use Fn* impls from the crate
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index b0d72e52..b85bbfdd 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2024,6 +2024,12 @@ namespace {
const auto& ty_o = this->context.get_type(node.m_value->m_res_type);
TRACE_FUNCTION_F("CallValue: ty=" << ty_o);
+ // - Shadow (prevent ivar guessing) every parameter
+ this->context.equate_types_shadow(node.span(), node.m_res_type);
+ for( const auto& arg_node : node.m_args ) {
+ this->context.equate_types_shadow(node.span(), arg_node->m_res_type);
+ }
+
if( ty_o.m_data.is_Infer() ) {
// - Don't even bother
return ;
@@ -2118,12 +2124,22 @@ namespace {
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( cmp == ::HIR::Compare::Fuzzy )
+ TODO(node.span(), "Handle fuzzy match - " << impl);
+
+ auto tup = impl.get_trait_ty_param(0);
+ if( !tup.m_data.is_Tuple() )
+ ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup);
+ fcn_args_tup = mv$(tup);
+ fcn_ret = impl.get_type("Output");
+ ASSERT_BUG(node.span(), fcn_ret != ::HIR::TypeRef(), "Impl didn't have a type for Output - " << impl);
+ return true;
});
if( found ) {
- // TODO: Fill cache.
- TODO(node.span(), "Use found impl of FnOnce");
+ // Fill cache and leave the TU_MATCH
+ node.m_arg_types = mv$( fcn_args_tup.m_data.as_Tuple() );
+ node.m_arg_types.push_back( mv$(fcn_ret) );
+ node.m_trait_used = ::HIR::ExprNode_CallValue::TraitUsed::Unknown;
break ; // leaves TU_MATCH
}
}
@@ -2137,7 +2153,7 @@ namespace {
}
// Didn't find anything. Error?
- ERROR(node.span(), E0000, "Unable to find an implementation of Fn* for " << this->context.m_ivars.fmt_type(ty));
+ ERROR(node.span(), E0000, "Unable to find an implementation of Fn*"<<trait_pp<<" for " << this->context.m_ivars.fmt_type(ty));
}
node.m_arg_types = mv$( fcn_args_tup.m_data.as_Tuple() );
@@ -2167,7 +2183,8 @@ namespace {
ty_p = &ty_o;
while(deref_count-- > 0)
{
- ty_p = &this->context.get_type(*ty_p->m_data.as_Borrow().inner);
+ ty_p = this->context.m_resolve.autoderef(node.span(), *ty_p, tmp_type);
+ assert(ty_p);
node.m_value = this->context.create_autoderef( mv$(node.m_value), ty_p->clone() );
}
}