diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-14 12:58:59 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-14 12:58:59 +0800 |
commit | df0ebe559b0e91e796aff2bfc8b77460b05899b9 (patch) | |
tree | c36f4b7218b6d806fc3740d58a03ecbaf855fda9 | |
parent | 8c15fe23aef14ec613b8cb837f40acfb648a84dd (diff) | |
download | mrust-df0ebe559b0e91e796aff2bfc8b77460b05899b9.tar.gz |
HIR Typecheck Expr - ErasedType return checking
-rw-r--r-- | src/hir_typeck/common.cpp | 154 | ||||
-rw-r--r-- | src/hir_typeck/common.hpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 32 |
3 files changed, 143 insertions, 46 deletions
diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp index 79e1095e..dbe59702 100644 --- a/src/hir_typeck/common.cpp +++ b/src/hir_typeck/common.cpp @@ -115,50 +115,51 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) throw ""; } -::HIR::PathParams monomorphise_path_params_with(const Span& sp, const ::HIR::PathParams& tpl, t_cb_generic callback, bool allow_infer) -{ +::HIR::PathParams clone_ty_with__path_params(const Span& sp, const ::HIR::PathParams& tpl, t_cb_clone_ty callback) { ::HIR::PathParams rv; + rv.m_types.reserve( tpl.m_types.size() ); for( const auto& ty : tpl.m_types) - rv.m_types.push_back( monomorphise_type_with_inner(sp, ty, callback, allow_infer) ); + rv.m_types.push_back( clone_ty_with(sp, ty, callback) ); return rv; } -::HIR::GenericPath monomorphise_genericpath_with(const Span& sp, const ::HIR::GenericPath& tpl, t_cb_generic callback, bool allow_infer) -{ - return ::HIR::GenericPath( tpl.m_path, monomorphise_path_params_with(sp, tpl.m_params, callback, allow_infer) ); +::HIR::GenericPath clone_ty_with__generic_path(const Span& sp, const ::HIR::GenericPath& tpl, t_cb_clone_ty callback) { + return ::HIR::GenericPath( tpl.m_path, clone_ty_with__path_params(sp, tpl.m_params, callback) ); } -::HIR::TraitPath monomorphise_traitpath_with(const Span& sp, const ::HIR::TraitPath& tpl, t_cb_generic callback, bool allow_infer) -{ +::HIR::TraitPath clone_ty_with__trait_path(const Span& sp, const ::HIR::TraitPath& tpl, t_cb_clone_ty callback) { ::HIR::TraitPath rv { - monomorphise_genericpath_with(sp, tpl.m_path, callback, allow_infer), + clone_ty_with__generic_path(sp, tpl.m_path, callback), tpl.m_hrls, {}, tpl.m_trait_ptr }; - for(const auto& assoc : tpl.m_type_bounds) - rv.m_type_bounds.insert(::std::make_pair( assoc.first, monomorphise_type_with_inner(sp, assoc.second, callback, allow_infer) )); + for(const auto& assoc : tpl.m_type_bounds) { + rv.m_type_bounds.insert(::std::make_pair( + assoc.first, + clone_ty_with(sp, assoc.second, callback) + )); + } return rv; } -::HIR::Path monomorphise_path_with(const Span& sp, const ::HIR::Path& tpl, t_cb_generic callback, bool allow_infer) -{ +::HIR::Path clone_ty_with__path(const Span& sp, const ::HIR::Path& tpl, t_cb_clone_ty callback) { TU_MATCH(::HIR::Path::Data, (tpl.m_data), (e2), (Generic, - return ::HIR::Path( monomorphise_genericpath_with(sp, e2, callback, allow_infer) ); + return ::HIR::Path( clone_ty_with__generic_path(sp, e2, callback) ); ), (UfcsKnown, return ::HIR::Path::Data::make_UfcsKnown({ - box$( monomorphise_type_with_inner(sp, *e2.type, callback, allow_infer) ), - monomorphise_genericpath_with(sp, e2.trait, callback, allow_infer), + box$( clone_ty_with(sp, *e2.type, callback) ), + clone_ty_with__generic_path(sp, e2.trait, callback), e2.item, - monomorphise_path_params_with(sp, e2.params, callback, allow_infer) + clone_ty_with__path_params(sp, e2.params, callback) }); ), (UfcsUnknown, return ::HIR::Path::Data::make_UfcsUnknown({ - box$( monomorphise_type_with_inner(sp, *e2.type, callback, allow_infer) ), + box$( clone_ty_with(sp, *e2.type, callback) ), e2.item, - monomorphise_path_params_with(sp, e2.params, callback, allow_infer) + clone_ty_with__path_params(sp, e2.params, callback) }); ), (UfcsInherent, @@ -167,17 +168,18 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) ) throw ""; } -::HIR::TypeRef monomorphise_type_with_inner(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer) +::HIR::TypeRef clone_ty_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_clone_ty callback) { ::HIR::TypeRef rv; + + if( callback(tpl, rv) ) { + DEBUG(tpl << " => " << rv); + return rv; + } + TU_MATCH(::HIR::TypeRef::Data, (tpl.m_data), (e), (Infer, - if( allow_infer ) { - rv = ::HIR::TypeRef(e); - } - else { - BUG(sp, "_ type found in monomorphisation target"); - } + rv = ::HIR::TypeRef(e); ), (Diverge, rv = ::HIR::TypeRef(e); @@ -187,7 +189,7 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) ), (Path, rv = ::HIR::TypeRef( ::HIR::TypeRef::Data::Data_Path { - monomorphise_path_with(sp, e.path, callback, allow_infer), + clone_ty_with__path(sp, e.path, callback), e.binding.clone() } ); // If the input binding was Opaque, clear it back to Unbound @@ -196,26 +198,25 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) } ), (Generic, - rv = callback(tpl).clone(); - DEBUG(tpl << " => " << rv); + rv = ::HIR::TypeRef(e); ), (TraitObject, ::HIR::TypeRef::Data::Data_TraitObject to; - to.m_trait = monomorphise_traitpath_with(sp, e.m_trait, callback, allow_infer); + to.m_trait = clone_ty_with__trait_path(sp, e.m_trait, callback); for(const auto& trait : e.m_markers) { - to.m_markers.push_back( monomorphise_genericpath_with(sp, trait, callback, allow_infer) ); + to.m_markers.push_back( clone_ty_with__generic_path(sp, trait, callback) ); } to.m_lifetime = e.m_lifetime; rv = ::HIR::TypeRef( mv$(to) ); ), (ErasedType, - auto origin = monomorphise_path_with(sp, e.m_origin, callback, allow_infer); + auto origin = clone_ty_with__path(sp, e.m_origin, callback); ::std::vector< ::HIR::TraitPath> traits; traits.reserve( e.m_traits.size() ); for(const auto& trait : e.m_traits) - traits.push_back( monomorphise_traitpath_with(sp, trait, callback, allow_infer) ); + traits.push_back( clone_ty_with__trait_path(sp, trait, callback) ); rv = ::HIR::TypeRef( ::HIR::TypeRef::Data::Data_ErasedType { mv$(origin), e.m_index, @@ -227,44 +228,111 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) if( e.size_val == ~0u ) { BUG(sp, "Attempting to clone array with unknown size - " << tpl); } - rv = ::HIR::TypeRef::new_array( monomorphise_type_with_inner(sp, *e.inner, callback, allow_infer), e.size_val ); + rv = ::HIR::TypeRef::new_array( clone_ty_with(sp, *e.inner, callback), e.size_val ); ), (Slice, - rv = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Slice({ box$(monomorphise_type_with_inner(sp, *e.inner, callback, allow_infer)) }) ); + rv = ::HIR::TypeRef::new_slice( clone_ty_with(sp, *e.inner, callback) ); ), (Tuple, ::std::vector< ::HIR::TypeRef> types; for(const auto& ty : e) { - types.push_back( monomorphise_type_with_inner(sp, ty, callback, allow_infer) ); + types.push_back( clone_ty_with(sp, ty, callback) ); } rv = ::HIR::TypeRef( mv$(types) ); ), (Borrow, - rv = ::HIR::TypeRef::new_borrow(e.type, monomorphise_type_with_inner(sp, *e.inner, callback, allow_infer)); + rv = ::HIR::TypeRef::new_borrow (e.type, clone_ty_with(sp, *e.inner, callback)); ), (Pointer, - rv = ::HIR::TypeRef::new_pointer(e.type, monomorphise_type_with_inner(sp, *e.inner, callback, allow_infer)); + rv = ::HIR::TypeRef::new_pointer(e.type, clone_ty_with(sp, *e.inner, callback)); ), (Function, ::HIR::FunctionType ft; ft.is_unsafe = e.is_unsafe; ft.m_abi = e.m_abi; - ft.m_rettype = box$( monomorphise_type_with_inner(sp, *e.m_rettype, callback, allow_infer) ); + ft.m_rettype = box$( clone_ty_with(sp, *e.m_rettype, callback) ); for( const auto& arg : e.m_arg_types ) - ft.m_arg_types.push_back( monomorphise_type_with_inner(sp, arg, callback, allow_infer) ); + ft.m_arg_types.push_back( clone_ty_with(sp, arg, callback) ); rv = ::HIR::TypeRef( mv$(ft) ); ), (Closure, ::HIR::TypeRef::Data::Data_Closure oe; oe.node = e.node; - oe.m_rettype = box$( monomorphise_type_with_inner(sp, *e.m_rettype, callback, allow_infer) ); + oe.m_rettype = box$( clone_ty_with(sp, *e.m_rettype, callback) ); for(const auto& a : e.m_arg_types) - oe.m_arg_types.push_back( monomorphise_type_with_inner(sp, a, callback, allow_infer) ); - rv = ::HIR::TypeRef(::HIR::TypeRef::Data::make_Closure( mv$(oe) )); + oe.m_arg_types.push_back( clone_ty_with(sp, a, callback) ); + rv = ::HIR::TypeRef( mv$(oe) ); ) ) return rv; } + +::HIR::PathParams monomorphise_path_params_with(const Span& sp, const ::HIR::PathParams& tpl, t_cb_generic callback, bool allow_infer) +{ + ::HIR::PathParams rv; + for( const auto& ty : tpl.m_types) + rv.m_types.push_back( monomorphise_type_with_inner(sp, ty, callback, allow_infer) ); + return rv; +} +::HIR::GenericPath monomorphise_genericpath_with(const Span& sp, const ::HIR::GenericPath& tpl, t_cb_generic callback, bool allow_infer) +{ + return ::HIR::GenericPath( tpl.m_path, monomorphise_path_params_with(sp, tpl.m_params, callback, allow_infer) ); +} +::HIR::TraitPath monomorphise_traitpath_with(const Span& sp, const ::HIR::TraitPath& tpl, t_cb_generic callback, bool allow_infer) +{ + ::HIR::TraitPath rv { + monomorphise_genericpath_with(sp, tpl.m_path, callback, allow_infer), + tpl.m_hrls, + {}, + tpl.m_trait_ptr + }; + + for(const auto& assoc : tpl.m_type_bounds) + rv.m_type_bounds.insert(::std::make_pair( assoc.first, monomorphise_type_with_inner(sp, assoc.second, callback, allow_infer) )); + + return rv; +} +::HIR::Path monomorphise_path_with(const Span& sp, const ::HIR::Path& tpl, t_cb_generic callback, bool allow_infer) +{ + TU_MATCH(::HIR::Path::Data, (tpl.m_data), (e2), + (Generic, + return ::HIR::Path( monomorphise_genericpath_with(sp, e2, callback, allow_infer) ); + ), + (UfcsKnown, + return ::HIR::Path::Data::make_UfcsKnown({ + box$( monomorphise_type_with_inner(sp, *e2.type, callback, allow_infer) ), + monomorphise_genericpath_with(sp, e2.trait, callback, allow_infer), + e2.item, + monomorphise_path_params_with(sp, e2.params, callback, allow_infer) + }); + ), + (UfcsUnknown, + return ::HIR::Path::Data::make_UfcsUnknown({ + box$( monomorphise_type_with_inner(sp, *e2.type, callback, allow_infer) ), + e2.item, + monomorphise_path_params_with(sp, e2.params, callback, allow_infer) + }); + ), + (UfcsInherent, + TODO(sp, "UfcsInherent - " << tpl); + ) + ) + throw ""; +} +::HIR::TypeRef monomorphise_type_with_inner(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer) +{ + return clone_ty_with(sp, tpl, [&](const auto& tpl, auto& rv) { + if( tpl.m_data.is_Infer() && !allow_infer ) + BUG(sp, "_ type found in monomorphisation target"); + + if( tpl.m_data.is_Generic() ) { + rv = callback(tpl).clone(); + return true; + } + + return false; + }); +} ::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer) { ::HIR::TypeRef rv; diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp index ce569351..3a1e5c2a 100644 --- a/src/hir_typeck/common.hpp +++ b/src/hir_typeck/common.hpp @@ -28,6 +28,9 @@ extern ::HIR::TraitPath monomorphise_traitpath_with(const Span& sp, const ::HIR: extern ::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer=true); extern ::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl); +typedef ::std::function<bool(const ::HIR::TypeRef&, ::HIR::TypeRef&)> t_cb_clone_ty; +extern ::HIR::TypeRef clone_ty_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_clone_ty callback); + static inline t_cb_generic monomorphise_type_get_cb(const Span& sp, const ::HIR::TypeRef* self_ty, const ::HIR::PathParams* params_i, const ::HIR::PathParams* params_m, const ::HIR::PathParams* params_p=nullptr) { return [=](const auto& gt)->const auto& { diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 9338cbac..95206943 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -5129,13 +5129,39 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: // - Build up ruleset from node tree { + const Span& sp = root_ptr->span(); + // If the result type contans an erased type, replace that with a new ivar and emit trait bounds for it. + ::HIR::TypeRef new_res_ty = clone_ty_with(sp, result_type, [&](const auto& tpl, auto& rv) { + if( tpl.m_data.is_ErasedType() ) + { + const auto& e = tpl.m_data.as_ErasedType(); + // TODO: Save this ivar somewhere for users of this function. + rv = context.m_ivars.new_ivar_tr(); + for(const auto& trait : e.m_traits) + { + if( trait.m_type_bounds.size() == 0 ) + { + context.equate_types_assoc(sp, ::HIR::TypeRef(), trait.m_path.m_path, trait.m_path.m_params.clone(), rv, "", false); + } + else + { + for(const auto& aty : trait.m_type_bounds) + { + context.equate_types_assoc(sp, aty.second, trait.m_path.m_path, trait.m_path.m_params.clone(), rv, aty.first.c_str(), false); + } + } + } + return true; + } + return false; + }); + ExprVisitor_Enum visitor(context, ms.m_traits, result_type); context.add_ivars(root_ptr->m_res_type); root_ptr->visit(visitor); - //context.equate_types(expr->span(), result_type, root_ptr->m_res_type); - DEBUG("Return type = " << result_type); - context.equate_types_coerce(expr->span(), result_type, root_ptr); + DEBUG("Return type = " << new_res_ty); + context.equate_types_coerce(sp, new_res_ty, root_ptr); } const unsigned int MAX_ITERATIONS = 100; |