diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-07 12:42:35 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-07 12:42:35 +0800 |
commit | abc5759934306a55ba25016eeed9a522d81f20d3 (patch) | |
tree | 831a294ddf6de487a743ffe664ad49a3550d6725 | |
parent | 9bd69a093dc619aa0cc587924c74d5355a539bc5 (diff) | |
download | mrust-abc5759934306a55ba25016eeed9a522d81f20d3.tar.gz |
HIR Typecheck Static - Magic Fn impls for function pointers
-rw-r--r-- | src/hir_typeck/static.cpp | 34 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 6 |
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(); } |