summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-14 12:58:59 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-14 12:58:59 +0800
commitdf0ebe559b0e91e796aff2bfc8b77460b05899b9 (patch)
treec36f4b7218b6d806fc3740d58a03ecbaf855fda9
parent8c15fe23aef14ec613b8cb837f40acfb648a84dd (diff)
downloadmrust-df0ebe559b0e91e796aff2bfc8b77460b05899b9.tar.gz
HIR Typecheck Expr - ErasedType return checking
-rw-r--r--src/hir_typeck/common.cpp154
-rw-r--r--src/hir_typeck/common.hpp3
-rw-r--r--src/hir_typeck/expr_cs.cpp32
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;