summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-02-12 12:14:22 +0800
committerJohn Hodge <tpg@mutabah.net>2017-02-12 12:14:22 +0800
commit69ee1650192dfb687358aa72e55ac023eaad185f (patch)
treea5a1ef2e18bbbca8c870323fd4a2df0bc2952e42 /src
parentbd2d725b2bb013446ad7ed53e384cd1f38073be9 (diff)
downloadmrust-69ee1650192dfb687358aa72e55ac023eaad185f.tar.gz
MIR Gen - Alter handling of scopes to support diverging expressions
Diffstat (limited to 'src')
-rw-r--r--src/mir/from_hir.cpp24
-rw-r--r--src/mir/from_hir_match.cpp4
-rw-r--r--src/mir/mir_builder.cpp21
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;