summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-07 12:42:35 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-07 12:42:35 +0800
commitabc5759934306a55ba25016eeed9a522d81f20d3 (patch)
tree831a294ddf6de487a743ffe664ad49a3550d6725
parent9bd69a093dc619aa0cc587924c74d5355a539bc5 (diff)
downloadmrust-abc5759934306a55ba25016eeed9a522d81f20d3.tar.gz
HIR Typecheck Static - Magic Fn impls for function pointers
-rw-r--r--src/hir_typeck/static.cpp34
-rw-r--r--src/hir_typeck/static.hpp6
2 files changed, 36 insertions, 4 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index c8afdebf..5ad647cb 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -91,14 +91,43 @@ bool StaticTraitResolve::find_impl(
TRACE_FUNCTION_F(trait_path << FMT_CB(os, if(trait_params) { os << *trait_params; } else { os << "<?>"; }) << " for " << type);
auto cb_ident = [](const auto&ty)->const auto&{return ty;};
+ static ::HIR::PathParams null_params;
+
if( trait_path == m_lang_Copy ) {
if( this->type_is_copy(sp, type) ) {
- static ::HIR::PathParams null_params;
static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc;
return found_cb( ImplRef(&type, &null_params, &null_assoc) );
}
}
+ // --- MAGIC IMPLS ---
+ // TODO: There should be quite a few more here, but laziness
+ TU_IFLET(::HIR::TypeRef::Data, type.m_data, Function, e,
+ if( trait_path == m_lang_Fn || trait_path == m_lang_FnMut || trait_path == m_lang_FnOnce ) {
+ if( trait_params )
+ {
+ const auto& des_arg_tys = trait_params->m_types.at(0).m_data.as_Tuple();
+ if( des_arg_tys.size() != e.m_arg_types.size() ) {
+ return false;
+ }
+ for(unsigned int i = 0; i < des_arg_tys.size(); i ++)
+ {
+ if( des_arg_tys[i] != e.m_arg_types[i] ) {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ trait_params = &null_params;
+ }
+ ::std::map< ::std::string, ::HIR::TypeRef> assoc;
+ assoc.insert( ::std::make_pair("Output", e.m_rettype->clone()) );
+ return found_cb( ImplRef(type.clone(), trait_params->clone(), mv$(assoc)) );
+ }
+ )
+ // --- / ---
+
bool ret;
// TODO: A bound can imply something via its associated types. How deep can this go?
@@ -475,9 +504,6 @@ void StaticTraitResolve::expand_associated_types__UfcsKnown(const Span& sp, ::HI
ERROR(sp, E0000, "No associated type " << e2.item << " for trait " << e2.trait);
}
}
- else {
- ERROR(sp, E0000, "No implementation of " << e2.trait << " for " << *e2.type);
- }
//}
//else
//{
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index ecbdc6d7..d67e9dab 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -23,6 +23,9 @@ public:
::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities;
private:
::HIR::SimplePath m_lang_Copy;
+ ::HIR::SimplePath m_lang_Fn;
+ ::HIR::SimplePath m_lang_FnMut;
+ ::HIR::SimplePath m_lang_FnOnce;
public:
StaticTraitResolve(const ::HIR::Crate& crate):
@@ -31,6 +34,9 @@ public:
m_item_generics(nullptr)
{
m_lang_Copy = m_crate.get_lang_item_path(Span(), "copy");
+ m_lang_Fn = m_crate.get_lang_item_path(Span(), "fn");
+ m_lang_FnMut = m_crate.get_lang_item_path(Span(), "fn_mut");
+ m_lang_FnOnce = m_crate.get_lang_item_path(Span(), "fn_once");
prep_indexes();
}