summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-16 16:33:53 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-16 16:33:53 +0800
commit1ecea3af716a85d9bb5730f774a38894eb27c79b (patch)
tree86ecf472beafcece1c7a944abab5cf4e689313fb
parentc3a6cacd573c85bf07471718358bf5e260e389c4 (diff)
downloadmrust-1ecea3af716a85d9bb5730f774a38894eb27c79b.tar.gz
HIR Typecheck Expr - Refactor monomorphise_type_needed so the inner code can be used for a bugcheck.
-rw-r--r--src/hir_typeck/common.cpp176
-rw-r--r--src/hir_typeck/common.hpp6
-rw-r--r--src/hir_typeck/expr_cs.cpp15
3 files changed, 107 insertions, 90 deletions
diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp
index 2450f3fa..941e6002 100644
--- a/src/hir_typeck/common.cpp
+++ b/src/hir_typeck/common.cpp
@@ -8,21 +8,28 @@
#include "common.hpp"
#include <hir/path.hpp>
-bool monomorphise_type_needed(const ::HIR::TypeRef& tpl);
-::HIR::TypeRef monomorphise_type_with_inner(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer);
-
-bool monomorphise_pathparams_needed(const ::HIR::PathParams& tpl)
+bool visit_ty_with__path_params(const ::HIR::PathParams& tpl, t_cb_visit_ty callback)
{
for(const auto& ty : tpl.m_types)
- if( monomorphise_type_needed(ty) )
+ if( visit_ty_with(ty, callback) )
return true;
return false;
}
-bool monomorphise_path_needed(const ::HIR::Path& tpl)
+
+bool visit_ty_with__trait_path(const ::HIR::TraitPath& tpl, t_cb_visit_ty callback)
+{
+ if( visit_ty_with__path_params(tpl.m_path.m_params, callback) )
+ return true;
+ for(const auto& assoc : tpl.m_type_bounds)
+ if( visit_ty_with(assoc.second, callback) )
+ return true;
+ return false;
+}
+bool visit_ty_with__path(const ::HIR::Path& tpl, t_cb_visit_ty callback)
{
TU_MATCH(::HIR::Path::Data, (tpl.m_data), (e),
(Generic,
- return monomorphise_pathparams_needed(e.m_params);
+ return visit_ty_with__path_params(e.m_params, callback);
),
(UfcsInherent,
return monomorphise_type_needed(*e.type) || monomorphise_pathparams_needed(e.params);
@@ -36,85 +43,104 @@ bool monomorphise_path_needed(const ::HIR::Path& tpl)
)
throw "";
}
-bool monomorphise_traitpath_needed(const ::HIR::TraitPath& tpl)
+bool visit_ty_with(const ::HIR::TypeRef& ty, t_cb_visit_ty callback)
{
- if( monomorphise_pathparams_needed(tpl.m_path.m_params) ) return true;
- for(const auto& assoc : tpl.m_type_bounds)
- if( monomorphise_type_needed(assoc.second) )
- return true;
- return false;
-}
-bool monomorphise_type_needed(const ::HIR::TypeRef& tpl)
-{
- TU_MATCH(::HIR::TypeRef::Data, (tpl.m_data), (e),
+ if( callback(ty) ) {
+ return true;
+ }
+
+ TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e),
(Infer,
- BUG(Span(), "_ type found in monomorphisation target - " << tpl);
+ //BUG(Span(), "_ type found in monomorphisation target - " << tpl);
),
(Diverge,
- return false;
),
(Primitive,
- return false;
- ),
- (Path,
- return monomorphise_path_needed(e.path);
),
(Generic,
- return true;
+ ),
+ (Path,
+ return visit_ty_with__path(e.path, callback);
),
(TraitObject,
- if( monomorphise_traitpath_needed(e.m_trait) )
+ if( visit_ty_with__trait_path(e.m_trait, callback) )
return true;
for(const auto& trait : e.m_markers)
- if( monomorphise_pathparams_needed(trait.m_params) )
+ if( visit_ty_with__path_params(trait.m_params, callback) )
return true;
return false;
),
(ErasedType,
- if( monomorphise_path_needed(e.m_origin) )
+ if( visit_ty_with__path(e.m_origin, callback) )
return true;
for(const auto& trait : e.m_traits)
- if( monomorphise_traitpath_needed(trait) )
+ if( visit_ty_with__trait_path(trait, callback) )
return true;
return false;
),
(Array,
- return monomorphise_type_needed(*e.inner);
+ return visit_ty_with(*e.inner, callback);
),
(Slice,
- return monomorphise_type_needed(*e.inner);
+ return visit_ty_with(*e.inner, callback);
),
(Tuple,
for(const auto& ty : e) {
- if( monomorphise_type_needed(ty) )
+ if( visit_ty_with(ty, callback) )
return true;
}
return false;
),
(Borrow,
- return monomorphise_type_needed(*e.inner);
+ return visit_ty_with(*e.inner, callback);
),
(Pointer,
- return monomorphise_type_needed(*e.inner);
+ return visit_ty_with(*e.inner, callback);
),
(Function,
for(const auto& ty : e.m_arg_types) {
- if( monomorphise_type_needed(ty) )
+ if( visit_ty_with(ty, callback) )
return true;
}
- return monomorphise_type_needed(*e.m_rettype);
+ return visit_ty_with(*e.m_rettype, callback);
),
(Closure,
for(const auto& ty : e.m_arg_types) {
- if( monomorphise_type_needed(ty) )
+ if( visit_ty_with(ty, callback) )
return true;
}
- return monomorphise_type_needed(*e.m_rettype);
+ return visit_ty_with(*e.m_rettype, callback);
)
)
- throw "";
+ return false;
}
+bool monomorphise_pathparams_needed(const ::HIR::PathParams& tpl)
+{
+ return visit_ty_with__path_params(tpl, [&](const auto& ty) {
+ return (ty.m_data.is_Generic() ? true : false);
+ });
+}
+bool monomorphise_traitpath_needed(const ::HIR::TraitPath& tpl)
+{
+ return visit_ty_with__trait_path(tpl, [&](const auto& ty) {
+ return (ty.m_data.is_Generic() ? true : false);
+ });
+}
+bool monomorphise_path_needed(const ::HIR::Path& tpl)
+{
+ return visit_ty_with__path(tpl, [&](const auto& ty) {
+ return (ty.m_data.is_Generic() ? true : false);
+ });
+}
+bool monomorphise_type_needed(const ::HIR::TypeRef& tpl)
+{
+ return visit_ty_with(tpl, [&](const auto& ty) {
+ return (ty.m_data.is_Generic() ? true : false);
+ });
+}
+
+
::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() );
@@ -271,71 +297,43 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl)
return rv;
}
+namespace {
+ template<typename T>
+ t_cb_clone_ty monomorphise_type_with__closure(const Span& sp, const T& outer_tpl, t_cb_generic& callback, bool allow_infer)
+ {
+ return [&sp,&outer_tpl,callback,allow_infer](const auto& tpl, auto& rv) {
+ if( tpl.m_data.is_Infer() && !allow_infer )
+ BUG(sp, "_ type found in " << outer_tpl);
+
+ if( tpl.m_data.is_Generic() ) {
+ rv = callback(tpl).clone();
+ return true;
+ }
+
+ return false;
+ };
+ }
+}
+
::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;
+ return clone_ty_with__path_params(sp, tpl, monomorphise_type_with__closure(sp, tpl, callback, allow_infer));
}
::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) );
+ return clone_ty_with__generic_path(sp, tpl, monomorphise_type_with__closure(sp, tpl, 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;
+ return clone_ty_with__trait_path(sp, tpl, monomorphise_type_with__closure(sp, tpl, callback, allow_infer));
}
::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 "";
+ return clone_ty_with__path(sp, tpl, monomorphise_type_with__closure(sp, tpl, callback, allow_infer));
}
::HIR::TypeRef monomorphise_type_with_inner(const Span& sp, const ::HIR::TypeRef& outer_tpl, t_cb_generic callback, bool allow_infer)
{
- return clone_ty_with(sp, outer_tpl, [&](const auto& tpl, auto& rv) {
- if( tpl.m_data.is_Infer() && !allow_infer )
- BUG(sp, "_ type found in " << outer_tpl);
-
- if( tpl.m_data.is_Generic() ) {
- rv = callback(tpl).clone();
- return true;
- }
-
- return false;
- });
+ return clone_ty_with(sp, outer_tpl, monomorphise_type_with__closure(sp, outer_tpl, callback, allow_infer));
}
::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer)
{
diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp
index 3a1e5c2a..7e203002 100644
--- a/src/hir_typeck/common.hpp
+++ b/src/hir_typeck/common.hpp
@@ -28,7 +28,13 @@ 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&)> t_cb_visit_ty;
+/// Calls the provided callback on every type seen when recursing the type.
+/// If the callback returns `true`, no further types are visited and the function returns `true`.
+extern bool visit_ty_with(const ::HIR::TypeRef& ty, t_cb_visit_ty callback);
+
typedef ::std::function<bool(const ::HIR::TypeRef&, ::HIR::TypeRef&)> t_cb_clone_ty;
+/// Clones a type, calling the provided callback on every type (optionally providing a replacement)
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)
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 7c260ddc..cb2439c7 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2982,7 +2982,20 @@ void Context::dump() const {
void Context::equate_types(const Span& sp, const ::HIR::TypeRef& li, const ::HIR::TypeRef& ri) {
// Instantly apply equality
TRACE_FUNCTION_F(li << " == " << ri);
-
+
+ visit_ty_with(ri, [&](const auto& ty) {
+ if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding >> 8 == 2 ) {
+ BUG(sp, "Type contained an impl placeholder parameter - " << ri);
+ }
+ return false;
+ });
+ visit_ty_with(li, [&](const auto& ty) {
+ if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding >> 8 == 2 ) {
+ BUG(sp, "Type contained an impl placeholder parameter - " << li);
+ }
+ return false;
+ });
+
// Check if the type contains a replacable associated type
::HIR::TypeRef l_tmp;
::HIR::TypeRef r_tmp;