diff options
-rw-r--r-- | src/mir/check.cpp | 15 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 8 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 3 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 7 |
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 |