diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-05-03 20:50:13 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-05-03 20:50:13 +0800 |
commit | fb51e6006dbdb67977438e2c73b901856e23da91 (patch) | |
tree | 6299f3fa3d61a4c48171c2710852e79b5bfe4247 | |
parent | 52a948b6b934b3ac8c14f3d52e21fe0acf803378 (diff) | |
download | mrust-fb51e6006dbdb67977438e2c73b901856e23da91.tar.gz |
HIR Typecheck - Handle closure types in static typecheck
-rw-r--r-- | src/hir_typeck/static.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 1dabb2c2..c71e71d7 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -7,6 +7,7 @@ */ #include "static.hpp" #include <algorithm> +#include <hir/expr.hpp> void StaticTraitResolve::prep_indexes() { @@ -163,6 +164,47 @@ bool StaticTraitResolve::find_impl( return found_cb( ImplRef(type.clone(), trait_params->clone(), mv$(assoc)), false ); } ) + if(const auto* e = type.m_data.opt_Closure()) + { + 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; + } + switch( e->node->m_class ) + { + case ::HIR::ExprNode_Closure::Class::Unknown: + break; + case ::HIR::ExprNode_Closure::Class::NoCapture: + break; + case ::HIR::ExprNode_Closure::Class::Once: + if( trait_path == m_lang_FnMut ) + return false; + case ::HIR::ExprNode_Closure::Class::Mut: + if( trait_path == m_lang_Fn ) + return false; + case ::HIR::ExprNode_Closure::Class::Shared: + break; + } + ::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)), false ); + } + } // ---- // TraitObject traits and supertraits |