diff options
author | John Hodge <tpg@mutabah.net> | 2017-02-12 12:14:22 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-02-12 12:14:22 +0800 |
commit | 69ee1650192dfb687358aa72e55ac023eaad185f (patch) | |
tree | a5a1ef2e18bbbca8c870323fd4a2df0bc2952e42 /src | |
parent | bd2d725b2bb013446ad7ed53e384cd1f38073be9 (diff) | |
download | mrust-69ee1650192dfb687358aa72e55ac023eaad185f.tar.gz |
MIR Gen - Alter handling of scopes to support diverging expressions
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/from_hir.cpp | 24 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 4 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 21 |
3 files changed, 24 insertions, 25 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 52e53cde..40e43f3b 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -383,16 +383,14 @@ namespace { auto stmt_scope = m_builder.new_scope_temp(sp); this->visit_node_ptr(subnode); - if( m_builder.has_result() ) { - // TODO: Drop. - m_builder.get_result(sp); - } - if( m_builder.block_active() ) { + if( m_builder.block_active() || m_builder.has_result() ) { + // TODO: Emit a drop + m_builder.get_result(sp); m_builder.terminate_scope(sp, mv$(stmt_scope)); } else { - auto _ = mv$(stmt_scope); + m_builder.terminate_scope(sp, mv$(stmt_scope), false); m_builder.set_cur_block( m_builder.new_bb_unlinked() ); diverged = true; @@ -422,8 +420,8 @@ namespace { } else { - { auto _ = mv$(stmt_scope); } - { auto _ = mv$(scope); } + m_builder.terminate_scope( node.span(), mv$(stmt_scope), false ); + m_builder.terminate_scope( node.span(), mv$(scope), false ); // Block diverged in final node. } } @@ -431,7 +429,7 @@ namespace { { if( diverged ) { - auto _ = mv$(scope); + m_builder.terminate_scope( node.span(), mv$(scope), false ); m_builder.end_block( ::MIR::Terminator::make_Diverge({}) ); // Don't set a result if there's no block. } @@ -617,8 +615,8 @@ namespace { m_builder.terminate_scope( node.span(), mv$(scope) ); } else { - { auto _ = mv$(tmp_scope); } - { auto _ = mv$(scope); } + m_builder.terminate_scope( node.span(), mv$(tmp_scope), false ); + m_builder.terminate_scope( node.span(), mv$(scope), false ); } } else { @@ -726,7 +724,7 @@ namespace { m_builder.end_block( ::MIR::Terminator::make_Goto(next_block) ); } else { - { auto _ = mv$(stmt_scope); } + m_builder.terminate_scope(node.span(), mv$(stmt_scope), false); m_builder.end_split_arm(node.span(), scope, false); } } @@ -745,7 +743,7 @@ namespace { m_builder.end_block( ::MIR::Terminator::make_Goto(next_block) ); } else { - { auto _ = mv$(stmt_scope); } + m_builder.terminate_scope(node.span(), mv$(stmt_scope), false); m_builder.end_split_arm(node.span(), scope, false); } } diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 43b60816..a657ffd5 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -310,8 +310,8 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod DEBUG("Arm diverged"); // Nothing need be done, as the block diverged. // - Drops were handled by the diverging block (if not, the below will panic) - { auto _ = mv$(tmp_scope); } - { auto _ = mv$(drop_scope); } + builder.terminate_scope( arm.m_code->span(), mv$(tmp_scope), false ); + builder.terminate_scope( arm.m_code->span(), mv$(drop_scope), false ); builder.end_split_arm( arm.m_code->span(), match_scope, false ); } else { diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index d9899dc8..16b0fd80 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -616,9 +616,11 @@ void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cl } auto& scope_def = m_scopes.at(scope.idx); - ASSERT_BUG( sp, scope_def.complete == false, "Terminating scope which is already terminated" ); + //if( emit_cleanup ) { + // ASSERT_BUG( sp, scope_def.complete == false, "Terminating scope which is already terminated" ); + //} - if( emit_cleanup ) + if( emit_cleanup && scope_def.complete == false ) { // 2. Emit drops for all non-moved variables (share with below) drop_scope_values(scope_def); @@ -663,7 +665,6 @@ void MirBuilder::terminate_scope_early(const Span& sp, const ScopeHandle& scope, if( !is_conditional ) { DEBUG("Complete scope " << idx); drop_scope_values(scope_def); - m_scope_stack.pop_back(); complete_scope(scope_def); } else { @@ -1029,23 +1030,23 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r void MirBuilder::end_split_arm_early(const Span& sp) { TRACE_FUNCTION_F(""); + size_t i = m_scope_stack.size(); // Terminate all scopes until a split is found. - while( ! m_scope_stack.empty() && ! (m_scopes.at( m_scope_stack.back() ).data.is_Split() || m_scopes.at( m_scope_stack.back() ).data.is_Loop()) ) + while( i -- && ! (m_scopes.at(m_scope_stack[i]).data.is_Split() || m_scopes.at(m_scope_stack[i]).data.is_Loop()) ) { - auto& scope_def = m_scopes[m_scope_stack.back()]; + auto& scope_def = m_scopes[m_scope_stack[i]]; // Fully drop the scope - DEBUG("Complete scope " << m_scope_stack.back()); + DEBUG("Complete scope " << m_scope_stack[i]); drop_scope_values(scope_def); - m_scope_stack.pop_back(); complete_scope(scope_def); } - if( !m_scope_stack.empty() ) + if( i < m_scope_stack.size() ) { - if( m_scopes.at( m_scope_stack.back() ).data.is_Split() ) + if( m_scopes.at( m_scope_stack[i] ).data.is_Split() ) { DEBUG("Early terminate split scope " << m_scope_stack.back()); - auto& sd = m_scopes[ m_scope_stack.back() ]; + auto& sd = m_scopes[ m_scope_stack[i] ]; auto& sd_split = sd.data.as_Split(); sd_split.arms.back().has_early_terminated = true; |