summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/helpers.cpp37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 540a2a90..d31b5b7d 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -940,13 +940,13 @@ bool TraitResolution::find_trait_impls(const Span& sp,
)
return callback( type, ::HIR::PathParams(), {} );
}
+
+ const auto& trait_fn = this->m_crate.get_lang_item_path(sp, "fn");
+ const auto& trait_fn_mut = this->m_crate.get_lang_item_path(sp, "fn_mut");
+ const auto& trait_fn_once = this->m_crate.get_lang_item_path(sp, "fn_once");
// Closures are magical. They're unnamable and all trait impls come from within the compiler
TU_IFLET(::HIR::TypeRef::Data, type.m_data, Closure, e,
- const auto trait_fn = this->m_crate.get_lang_item_path(sp, "fn");
- const auto trait_fn_mut = this->m_crate.get_lang_item_path(sp, "fn_mut");
- const auto trait_fn_once = this->m_crate.get_lang_item_path(sp, "fn_once");
-
if( trait == trait_fn || trait == trait_fn_mut || trait == trait_fn_once ) {
if( params.m_types.size() != 1 )
BUG(sp, "Fn* traits require a single tuple argument");
@@ -974,6 +974,35 @@ bool TraitResolution::find_trait_impls(const Span& sp,
}
)
+ // Magic Fn* trait impls for function pointers
+ TU_IFLET(::HIR::TypeRef::Data, type.m_data, Function, e,
+ if( trait == trait_fn || trait == trait_fn_mut || trait == trait_fn_once ) {
+ if( params.m_types.size() != 1 )
+ BUG(sp, "Fn* traits require a single tuple argument");
+
+ // NOTE: unsafe or non-rust ABI functions aren't valid
+ if( e.m_abi != "rust" || e.is_unsafe ) {
+ DEBUG("- No magic impl, wrong ABI or unsafe in " << type);
+ return false;
+ }
+ DEBUG("- Magic impl of Fn* for " << type);
+
+ ::std::vector< ::HIR::TypeRef> args;
+ for(const auto& at : e.m_arg_types) {
+ args.push_back( at.clone() );
+ }
+
+ // NOTE: This is a conditional "true", we know nothing about the move/mut-ness of this closure yet
+ // - Could we?
+ ::HIR::PathParams pp;
+ 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( type, pp, types );
+ }
+ // Continue
+ )
+
// 1. Search generic params
if( find_trait_impls_bound(sp, trait, params, type, callback) )
return true;