summaryrefslogtreecommitdiff
path: root/src/mir
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-16 23:31:43 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-16 23:31:43 +0800
commit5aea1a2a905cf4aff72a934c6550132c1d29ea68 (patch)
tree78bf158de11b7b720fe2bba87448f050dd03764b /src/mir
parent83f37af7a3d962753d8c6b7693d194d80b44b43c (diff)
downloadmrust-5aea1a2a905cf4aff72a934c6550132c1d29ea68.tar.gz
MIR - Fix unsizing between trait objects
Diffstat (limited to 'src/mir')
-rw-r--r--src/mir/cleanup.cpp9
-rw-r--r--src/mir/from_hir.cpp4
2 files changed, 10 insertions, 3 deletions
diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp
index ddaaa8da..0ba5e781 100644
--- a/src/mir/cleanup.cpp
+++ b/src/mir/cleanup.cpp
@@ -524,7 +524,8 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
if( src_ty.m_data.is_TraitObject() )
{
out_src_is_dst = true;
- out_meta_val = ::MIR::RValue::make_DstMeta({ ptr_value.clone() });
+ auto deref_ptr_val = ::MIR::LValue::make_Deref({ box$(ptr_value.clone()) });
+ out_meta_val = ::MIR::RValue::make_DstMeta({ mv$(deref_ptr_val) });
}
else
{
@@ -551,7 +552,8 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
if( source_is_dst )
{
auto ty_unit_ptr = ::HIR::TypeRef::new_pointer(::HIR::BorrowType::Shared, ::HIR::TypeRef::new_unit());
- auto thin_ptr_lval = mutator.in_temporary( mv$(ty_unit_ptr), ::MIR::RValue::make_DstPtr({ mv$(ptr_value) }) );
+ auto deref_ptr_val = ::MIR::LValue::make_Deref({ box$(ptr_value) });
+ auto thin_ptr_lval = mutator.in_temporary( mv$(ty_unit_ptr), ::MIR::RValue::make_DstPtr({ mv$(deref_ptr_val) }) );
return ::MIR::RValue::make_MakeDst({ mv$(thin_ptr_lval), mv$(meta_lval) });
}
@@ -901,10 +903,11 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
const auto& src_ty = state.get_lvalue_type(tmp, e.val);
// TODO: Unsize and CoerceUnsized operations
// - Unsize should create a fat pointer if the pointer class is known (vtable or len)
- TU_IFLET( ::HIR::TypeRef::Data, e.type.m_data, Borrow, te
+ TU_IFLET( ::HIR::TypeRef::Data, e.type.m_data, Borrow, te,
// > & -> & = Unsize, create DST based on the pointer class of the destination.
// (&-ptr being destination is otherwise invalid)
// TODO Share with the CoerceUnsized handling?
+ se.src = MIR_Cleanup_CoerceUnsized(state, mutator, e.type, src_ty, mv$(e.val));
)
// Casts to PhantomData are only valid from PhandomData, and are added by _CoerceUnsized
else if( state.m_resolve.is_type_phantom_data(e.type) )
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 72fe1645..7d5853dd 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -1089,6 +1089,7 @@ namespace {
}
),
(TraitObject,
+ #if 0
// TODO: Obtain the vtable if the destination is a trait object
// vtable exists as an unnamable associated type
const auto& trait = *e.m_trait.m_trait_ptr;
@@ -1115,6 +1116,9 @@ namespace {
);
m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(vtable_lval) }) );
+ #else
+ m_builder.set_result( node.span(), ::MIR::RValue::make_Cast({ mv$(ptr_lval), node.m_res_type.clone() }) );
+ #endif
)
)
}