diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-16 23:31:43 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-16 23:31:43 +0800 |
commit | 5aea1a2a905cf4aff72a934c6550132c1d29ea68 (patch) | |
tree | 78bf158de11b7b720fe2bba87448f050dd03764b /src/mir | |
parent | 83f37af7a3d962753d8c6b7693d194d80b44b43c (diff) | |
download | mrust-5aea1a2a905cf4aff72a934c6550132c1d29ea68.tar.gz |
MIR - Fix unsizing between trait objects
Diffstat (limited to 'src/mir')
-rw-r--r-- | src/mir/cleanup.cpp | 9 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 4 |
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 ) ) } |