summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mir/check.cpp15
-rw-r--r--src/mir/from_hir.cpp8
-rw-r--r--src/mir/from_hir_match.cpp3
-rw-r--r--src/mir/mir_builder.cpp7
4 files changed, 28 insertions, 5 deletions
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index f16c222e..1b405674 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -265,7 +265,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
val_state.ensure_valid(state, se.val);
),
(Cast,
- val_state.move_val(state, se.val);
+ // Well.. it's not exactly moved...
+ val_state.ensure_valid(state, se.val);
+ //val_state.move_val(state, se.val);
),
(BinOp,
val_state.move_val(state, se.val_l);
@@ -342,17 +344,26 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
),
(If,
// Push blocks
+ val_state.ensure_valid( state, e.cond );
to_visit_blocks.push_back( ::std::make_pair(e.bb0, val_state) );
to_visit_blocks.push_back( ::std::make_pair(e.bb1, ::std::move(val_state)) );
),
(Switch,
+ val_state.ensure_valid( state, e.val );
for(const auto& tgt : e.targets)
{
to_visit_blocks.push_back( ::std::make_pair(tgt, val_state) );
}
),
(Call,
- // TODO: Push blocks (with return valid only in one)
+ if( e.fcn.is_Value() )
+ val_state.ensure_valid( state, e.fcn.as_Value() );
+ for(const auto& arg : e.args)
+ val_state.ensure_valid( state, arg );
+ // Push blocks (with return valid only in one)
+ to_visit_blocks.push_back( ::std::make_pair(e.panic_block, val_state) );
+ val_state.mark_validity( state, e.ret_val, true );
+ to_visit_blocks.push_back( ::std::make_pair(e.ret_block, ::std::move(val_state)) );
)
)
}
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 7218563b..272cea48 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -355,7 +355,7 @@ namespace {
}
}
- // - For the last node, don't bother with a statement scope
+ // For the last node, specially handle.
if( node.m_yields_final )
{
auto& subnode = node.m_nodes.back();
@@ -594,14 +594,17 @@ namespace {
// 'true' branch
{
+ auto stmt_scope = m_builder.new_scope_temp(node.m_true->span());
m_builder.set_cur_block(true_branch);
this->visit_node_ptr(node.m_true);
if( m_builder.block_active() || m_builder.has_result() ) {
m_builder.push_stmt_assign( node.span(), result_val.clone(), m_builder.get_result(node.m_true->span()) );
+ m_builder.terminate_scope(node.span(), mv$(stmt_scope));
m_builder.end_split_arm(node.span(), scope, true);
m_builder.end_block( ::MIR::Terminator::make_Goto(next_block) );
}
else {
+ { auto _ = mv$(stmt_scope); }
m_builder.end_split_arm(node.span(), scope, false);
}
}
@@ -610,14 +613,17 @@ namespace {
m_builder.set_cur_block(false_branch);
if( node.m_false )
{
+ auto stmt_scope = m_builder.new_scope_temp(node.m_false->span());
this->visit_node_ptr(node.m_false);
if( m_builder.block_active() )
{
m_builder.push_stmt_assign( node.span(), result_val.clone(), m_builder.get_result(node.m_false->span()) );
+ m_builder.terminate_scope(node.span(), mv$(stmt_scope));
m_builder.end_block( ::MIR::Terminator::make_Goto(next_block) );
m_builder.end_split_arm(node.span(), scope, true);
}
else {
+ { auto _ = mv$(stmt_scope); }
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 f191f3fa..5b425976 100644
--- a/src/mir/from_hir_match.cpp
+++ b/src/mir/from_hir_match.cpp
@@ -251,6 +251,7 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod
// - Define variables from the first pattern
conv.define_vars_from(node.span(), arm.m_patterns.front());
+ auto pat_scope = builder.new_scope_split(node.span());
for( unsigned int pat_idx = 0; pat_idx < arm.m_patterns.size(); pat_idx ++ )
{
const auto& pat = arm.m_patterns[pat_idx];
@@ -273,7 +274,9 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod
conv.destructure_from( arm.m_code->span(), pat, match_val.clone(), true );
builder.pause_cur_block();
// NOTE: Paused block resumed upon successful match
+ builder.end_split_arm( arm.m_code->span(), pat_scope, true );
}
+ builder.terminate_scope( arm.m_code->span(), mv$(pat_scope) );
// TODO: If this pattern ignores fields with Drop impls, this will lead to leaks.
// - Ideally, this would trigger a drop of whatever wasn't already taken by the pattern.
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index c2f8b822..2300a207 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -341,9 +341,12 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val)
TU_MATCH_DEF(::MIR::LValue, (val), (e),
(
),
+ // TODO: This may not be correct, because it can change the drop points and ordering
+ // HACK: Working around cases where values are dropped while the result is not yet used.
(Deref,
- // TODO: This may not be correct, because it can change the drop points and ordering
- // HACK: Working around cases where values are dropped while the result is not yet used.
+ raise_variables(sp, *e.val);
+ ),
+ (Field,
raise_variables(sp, *e.val);
),
// Actual value types