diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-04 12:23:10 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-04 12:23:10 +0800 |
commit | ca59f1e56b2fb221a86b53f75708b36524cc7274 (patch) | |
tree | b6c580f3f28be3bf94dbfb0572f1e607752c7ced /src/mir/from_hir.cpp | |
parent | 06f283b0a4c9b3e22bce6041d8345f1be53f13b0 (diff) | |
download | mrust-ca59f1e56b2fb221a86b53f75708b36524cc7274.tar.gz |
HIR - Restructure _Unsize handling to operate on pointers
Diffstat (limited to 'src/mir/from_hir.cpp')
-rw-r--r-- | src/mir/from_hir.cpp | 94 |
1 files changed, 53 insertions, 41 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index dc890495..4a540c14 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -876,49 +876,61 @@ namespace { const auto& ty_out = node.m_res_type; const auto& ty_in = node.m_value->m_res_type; - TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_out.m_data), (e), - ( - TODO(node.span(), "MIR _Unsize to " << ty_out); - ), - // TODO: Unsize custom types containing a ?Size generic - See the Unsize trait - //(Path, - // ), - //(Generic, - // ), - (Slice, - if( ty_in.m_data.is_Array() ) - { - const auto& in_array = ty_in.m_data.as_Array(); - auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::Constant( static_cast<uint64_t>(in_array.size_val) ) ); - m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }) ); - } - else if( ty_in.m_data.is_Generic() ) - { - // HACK: FixedSizeArray uses `A: Unsize<[T]>` which will lead to the above code not working (as the size isn't known). - // - Maybe _Meta on the `&A` would work as a stopgap (since A: Sized, it won't collide with &[T] or similar) - auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::RValue::make_DstMeta({ ptr_lval.clone() }) ); - m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }) ); - } - else - { - ASSERT_BUG(node.span(), ty_in.m_data.is_Array(), "Unsize to slice from non-array - " << ty_in); - } - ), - (TraitObject, - // TODO: Obtain the vtable if the destination is a trait object - // vtable exists as an unnamable associated type + + if( ty_out.m_data.is_Borrow() && ty_in.m_data.is_Borrow() ) + { + const auto& oe = ty_out.m_data.as_Borrow(); + const auto& ie = ty_in.m_data.as_Borrow(); + const auto& ty_out = *oe.inner; + const auto& ty_in = *ie.inner; + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_out.m_data), (e), + ( + TODO(node.span(), "MIR _Unsize to " << ty_out); + ), + // TODO: Unsize custom types containing a ?Size generic - See the Unsize trait + //(Path, + // ), + //(Generic, + // ), + (Slice, + if( ty_in.m_data.is_Array() ) + { + const auto& in_array = ty_in.m_data.as_Array(); + auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::Constant( static_cast<uint64_t>(in_array.size_val) ) ); + m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }) ); + } + else if( ty_in.m_data.is_Generic() ) + { + // HACK: FixedSizeArray uses `A: Unsize<[T]>` which will lead to the above code not working (as the size isn't known). + // - Maybe _Meta on the `&A` would work as a stopgap (since A: Sized, it won't collide with &[T] or similar) + auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::RValue::make_DstMeta({ ptr_lval.clone() }) ); + m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }) ); + } + else + { + ASSERT_BUG(node.span(), ty_in.m_data.is_Array(), "Unsize to slice from non-array - " << ty_in); + } + ), + (TraitObject, + // TODO: Obtain the vtable if the destination is a trait object + // vtable exists as an unnamable associated type - ::HIR::Path vtable { ty_in.clone(), e.m_trait.m_path.clone(), "#vtable" }; - ::HIR::TypeRef vtable_type { {} }; - auto vtable_lval = m_builder.lvalue_or_temp( - node.span(), - ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, mv$(vtable_type)), - ::MIR::RValue( ::MIR::Constant::make_ItemAddr(mv$(vtable)) ) - ); - - m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(vtable_lval) }) ); + ::HIR::Path vtable { ty_in.clone(), e.m_trait.m_path.clone(), "#vtable" }; + ::HIR::TypeRef vtable_type { {} }; + auto vtable_lval = m_builder.lvalue_or_temp( + node.span(), + ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, mv$(vtable_type)), + ::MIR::RValue( ::MIR::Constant::make_ItemAddr(mv$(vtable)) ) + ); + + m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(vtable_lval) }) ); + ) ) - ) + } + else + { + TODO(node.span(), "Support emitting CoerceUnsized-based _Unsize ops in MIR - " << ty_in << " -> " << ty_out); + } } void visit(::HIR::ExprNode_Index& node) override { |