diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-07 09:57:01 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-07 09:57:01 +0800 |
commit | d47803233fdc6a5576d5eb9f4495bce61f42ff7a (patch) | |
tree | 5e2137126b4756927a11cfc85ee74fb7cd5ad262 | |
parent | 84f82d42a8bd56f1f9dbd62d9d0255554002d315 (diff) | |
download | mrust-d47803233fdc6a5576d5eb9f4495bce61f42ff7a.tar.gz |
MIR Gen - Cleaner Box support, start on move-out structure
-rw-r--r-- | src/mir/from_hir.cpp | 14 | ||||
-rw-r--r-- | src/mir/from_hir.hpp | 5 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 83 |
3 files changed, 79 insertions, 23 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 5a0ca03a..59714d8b 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1008,17 +1008,11 @@ namespace { TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_val.m_data), (te), ( - if( m_builder.lang_Box() ) + if( m_builder.is_type_owned_box( ty_val ) ) { - if( ty_val.m_data.is_Path() - && ty_val.m_data.as_Path().path.m_data.is_Generic() - && ty_val.m_data.as_Path().path.m_data.as_Generic().m_path == *m_builder.lang_Box() - ) - { - // Box magically derefs. - // HACK: Break out of the switch used for TU_MATCH_DEF - break; - } + // Box magically derefs. + // HACK: Break out of the switch used for TU_MATCH_DEF + break; } BUG(sp, "Deref on unsupported type - " << ty_val); ), diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index 1f9007a5..475087c7 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -116,6 +116,11 @@ public: const ::HIR::SimplePath* lang_Box() const { return m_lang_Box; } const ::HIR::Crate& crate() const { return m_resolve.m_crate; } + //::HIR::TypeRef* is_type_owned_box(::HIR::TypeRef& ty) const { + //} + /// Check if the passed type is Box<T> and returns a pointer to the T type if so, otherwise nullptr + const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const; + // - Values ::MIR::LValue new_temporary(const ::HIR::TypeRef& ty); ::MIR::LValue lvalue_or_temp(const Span& sp, const ::HIR::TypeRef& ty, ::MIR::RValue val); diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index eb40f58b..b53a9356 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -50,6 +50,32 @@ MirBuilder::~MirBuilder() } } +const ::HIR::TypeRef* MirBuilder::is_type_owned_box(const ::HIR::TypeRef& ty) const +{ + if( m_lang_Box ) + { + if( ! ty.m_data.is_Path() ) { + return nullptr; + } + const auto& te = ty.m_data.as_Path(); + + if( ! te.path.m_data.is_Generic() ) { + return nullptr; + } + const auto& pe = te.path.m_data.as_Generic(); + + if( pe.m_path != *m_lang_Box ) { + return nullptr; + } + // TODO: Properly assert? + return &pe.m_params.m_types.at(0); + } + else + { + return nullptr; + } +} + void MirBuilder::define_variable(unsigned int idx) { DEBUG("DEFINE var" << idx << ": " << m_output.named_variables.at(idx)); @@ -658,19 +684,9 @@ void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std:: BUG(sp, "Deref on unexpected type - " << ty); ), (Path, - if( m_lang_Box ) + if( const auto* inner_ptr = this->is_type_owned_box(ty) ) { - TU_IFLET( ::HIR::Path::Data, te.path.m_data, Generic, e, - if( e.m_path == *m_lang_Box ) { - cb( e.m_params.m_types.at(0) ); - } - else { - BUG(sp, "Deref on unexpected type - " << ty); - } - ) - else { - BUG(sp, "Deref on unexpected type - " << ty); - } + cb( *inner_ptr ); } else { BUG(sp, "Deref on unexpected type - " << ty); @@ -934,7 +950,48 @@ void MirBuilder::moved_lvalue(const Span& sp, const ::MIR::LValue& lv) if( lvalue_is_copy(sp, lv) ) { } else { - // TODO: Move out of owned_box _is_ valid, and marks the box slot for shallow drop + // HACK: If the dereferenced type is a Box ("owned_box") then hack in move and shallow drop + if( this->m_lang_Box ) + { + bool is_box = false; + with_val_type(sp, *e.val, [&](const auto& ty){ + is_box = this->is_type_owned_box(ty); + }); + if( is_box ) + { + ::MIR::LValue inner_lv; + // 1. If the inner lvalue isn't a slot with move information, move out of the lvalue into a temporary (with standard temp scope) + TU_MATCH_DEF( ::MIR::LValue, (*e.val), (ei), + ( + TODO(sp, "Move Box out of indirect access " << *e.val << " and into a temp"); + ), + (Variable, + inner_lv = ::MIR::LValue(ei); + ), + (Temporary, + inner_lv = ::MIR::LValue(ei); + ), + (Argument, + inner_lv = ::MIR::LValue(ei); + ) + ) + // 2. Mark the slot as requiring only a shallow drop + TU_MATCH_DEF( ::MIR::LValue, (inner_lv), (ei), + ( + BUG(sp, "Box move out of invalid LValue " << inner_lv << " - should have been moved"); + ), + (Variable, + TODO(sp, "Mark var " << ei << " for shallow drop"); + ), + (Temporary, + TODO(sp, "Mark temp " << ei.idx << " for shallow drop"); + ), + (Argument, + TODO(sp, "Mark arg " << ei.idx << " for shallow drop"); + ) + ) + } + } BUG(sp, "Move out of deref with non-Copy values - &move? - " << lv); moved_lvalue(sp, *e.val); } |