summaryrefslogtreecommitdiff
path: root/src/hir_typeck
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-08-05 10:04:21 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-08-05 10:04:21 +0800
commitb38a7b6ce8bdaa61b5e59150e0c466190476cb6e (patch)
tree14eeea30c13c5c6ae99dffbc01566b8438c73a57 /src/hir_typeck
parentcece72809d4c70debea23fd832e4830d334f52d6 (diff)
downloadmrust-b38a7b6ce8bdaa61b5e59150e0c466190476cb6e.tar.gz
Typecheck Expr - Infer smart pointer type
Diffstat (limited to 'src/hir_typeck')
-rw-r--r--src/hir_typeck/expr_cs.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 84442a1b..5303c432 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -4452,8 +4452,38 @@ namespace {
}
return false;
}
+
+ static ::HIR::TypeRef make_pruned(Context& context, const ::HIR::TypeRef& ty)
+ {
+ const auto& binding = ty.m_data.as_Path().binding;
+ const auto& sm = binding.as_Struct()->m_struct_markings;
+ ::HIR::GenericPath gp = ty.m_data.as_Path().path.m_data.as_Generic().clone();
+ if( sm.coerce_param == ~0u ) {
+ for(size_t i = 0; i < gp.m_params.m_types.size(); i ++ )
+ gp.m_params.m_types.at(i) = context.m_ivars.new_ivar_tr();
+ }
+ else {
+ gp.m_params.m_types.at(sm.coerce_param) = context.m_ivars.new_ivar_tr();
+ }
+ return ::HIR::TypeRef::new_path(mv$(gp), binding.as_Struct());
+ }
};
+ // Coercing to a CoerceUnsized type can only happen from something of the same generic type
+ // - Create a copy of the known type, but with the `Coerce` parameter set to a new ivar
+ if( ty_src.m_data.is_Infer() && H::type_has_coerce_path(context, ty_dst) && ty_dst.m_data.as_Path().binding.is_Struct() )
+ {
+ DEBUG("Create ivar filled version of " << ty_dst);
+ context.equate_types(sp, ty_src, H::make_pruned(context, ty_dst));
+ return false;
+ }
+ if( ty_dst.m_data.is_Infer() && H::type_has_coerce_path(context, ty_src) && ty_src.m_data.as_Path().binding.is_Struct() )
+ {
+ DEBUG("Create ivar filled version of " << ty_src);
+ context.equate_types(sp, ty_dst, H::make_pruned(context, ty_src));
+ return false;
+ }
+
// CoerceUnsized trait
// - Only valid for generic or path destination types
if( ty_dst.m_data.is_Generic() || H::type_has_coerce_path(context, ty_dst) )