diff options
| -rw-r--r-- | src/mir/from_hir.cpp | 2 | ||||
| -rw-r--r-- | src/mir/from_hir.hpp | 3 | ||||
| -rw-r--r-- | src/mir/mir_builder.cpp | 64 | 
3 files changed, 42 insertions, 27 deletions
| diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 98d339e3..f014961a 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1452,6 +1452,8 @@ namespace {              }              else              { +                // NOTE: This has to be done here because the builder can't easily do it. +                m_builder.mark_value_assigned(node.span(), res);              }              m_builder.set_result( node.span(), mv$(res) );          } diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index e7492df6..3fd933fc 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -156,6 +156,9 @@ public:          return m_block_active;      } +    // Mark a value as initialised (used for Call, because it has to be done after the panic block is populated) +    void mark_value_assigned(const Span& sp, const ::MIR::LValue& val); +          void set_cur_block(unsigned int new_block);      ::MIR::BasicBlockId pause_cur_block();      void end_block(::MIR::Terminator term); diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index d539ef89..86dde1ac 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -251,6 +251,37 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal      )      // Drop target if populated +    mark_value_assigned(sp, dst); +    m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Assign({ mv$(dst), mv$(val) }) ); +} +void MirBuilder::push_stmt_drop(const Span& sp, ::MIR::LValue val) +{ +    ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); +    ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); +     +    if( lvalue_is_copy(sp, val) ) { +        // Don't emit a drop for Copy values +        return ; +    } +     +    m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::DEEP, mv$(val) }) ); +} +void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val) +{ +    ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); +    ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); +     +    // TODO: Ensure that the type is a Box +    //if( lvalue_is_copy(sp, val) ) { +    //    // Don't emit a drop for Copy values +    //    return ; +    //} +     +    m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::SHALLOW, mv$(val) }) ); +} + +void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst) +{      TU_MATCH_DEF(::MIR::LValue, (dst), (e),      (          ), @@ -303,32 +334,6 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal          set_variable_state(sp, e, VarState::Init);          )      ) -    m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Assign({ mv$(dst), mv$(val) }) ); -} -void MirBuilder::push_stmt_drop(const Span& sp, ::MIR::LValue val) -{ -    ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); -    ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); -     -    if( lvalue_is_copy(sp, val) ) { -        // Don't emit a drop for Copy values -        return ; -    } -     -    m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::DEEP, mv$(val) }) ); -} -void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val) -{ -    ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); -    ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); -     -    // TODO: Ensure that the type is a Box -    //if( lvalue_is_copy(sp, val) ) { -    //    // Don't emit a drop for Copy values -    //    return ; -    //} -     -    m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::SHALLOW, mv$(val) }) );  }  void MirBuilder::set_cur_block(unsigned int new_block) @@ -412,7 +417,7 @@ ScopeHandle MirBuilder::new_scope_loop(const Span& sp)  }  void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cleanup/*=true*/)  { -    DEBUG("DONE scope " << scope.idx); +    DEBUG("DONE scope " << scope.idx << " - " << (emit_cleanup ? "CLEANUP" : "NO CLEANUP"));      // 1. Check that this is the current scope (at the top of the stack)      if( m_scope_stack.empty() || m_scope_stack.back() != scope.idx )      { @@ -989,8 +994,13 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd)              switch( get_temp_state(sd.span, tmp_idx) )              {              case VarState::Uninit: +                DEBUG("Temporary " << tmp_idx << " Uninit"); +                break;              case VarState::Dropped: +                DEBUG("Temporary " << tmp_idx << " Dropped"); +                break;              case VarState::Moved: +                DEBUG("Temporary " << tmp_idx << " Moved");                  break;              case VarState::Init:                  push_stmt_drop( sd.span, ::MIR::LValue::make_Temporary({ tmp_idx }) ); | 
