summaryrefslogtreecommitdiff
path: root/src/mir
diff options
context:
space:
mode:
Diffstat (limited to 'src/mir')
-rw-r--r--src/mir/from_hir.cpp46
1 files changed, 19 insertions, 27 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index d30140e4..8951599b 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -333,14 +333,11 @@ namespace {
// NOTE: This doesn't create a BB, as BBs are not needed for scoping
if( node.m_nodes.size() > 0 )
{
- bool res_valid;
- ::MIR::RValue res;
bool diverged = false;
- auto block_res = m_builder.new_temporary(node.m_res_type);
auto scope = m_builder.new_scope_var(node.span());
- for(unsigned int i = 0; i < node.m_nodes.size()-1; i ++)
+ for(unsigned int i = 0; i < node.m_nodes.size() - (node.m_yields_final ? 1 : 0); i ++)
{
auto& subnode = node.m_nodes[i];
const Span& sp = subnode->span();
@@ -364,49 +361,44 @@ namespace {
}
// - For the last node, don't bother with a statement scope
+ if( node.m_yields_final )
{
auto& subnode = node.m_nodes.back();
const Span& sp = subnode->span();
auto stmt_scope = m_builder.new_scope_temp(sp);
this->visit_node_ptr(subnode);
- if( m_builder.has_result() || m_builder.block_active() ) {
+ if( m_builder.has_result() || m_builder.block_active() )
+ {
ASSERT_BUG(sp, m_builder.block_active(), "Result yielded, but no active block");
ASSERT_BUG(sp, m_builder.has_result(), "Active block but no result yeilded");
// PROBLEM: This can drop the result before we want to use it.
- res = m_builder.get_result(sp);
+ auto res = m_builder.get_result(sp);
m_builder.raise_variables(sp, res);
m_builder.terminate_scope(sp, mv$(stmt_scope));
- res_valid = true;
+ m_builder.terminate_scope( node.span(), mv$(scope) );
+ m_builder.set_result( node.span(), mv$(res) );
}
- else {
- auto _ = mv$(stmt_scope);
- res_valid = false;
+ else
+ {
+ { auto _ = mv$(stmt_scope); }
+ { auto _ = mv$(scope); }
+ // Block diverged in final node.
}
}
-
- // Drop all bindings introduced during this block.
- if( m_builder.block_active() ) {
- if( diverged ) {
+ else
+ {
+ if( diverged )
+ {
auto _ = mv$(scope);
m_builder.end_block( ::MIR::Terminator::make_Diverge({}) );
+ // Don't set a result if there's no block.
}
- else {
+ else
+ {
m_builder.terminate_scope( node.span(), mv$(scope) );
- }
- }
- else {
- auto _ = mv$(scope);
- }
-
- // Result from last node (if it didn't diverge)
- if( res_valid ) {
- if( node.m_yields_final ) {
- m_builder.set_result( node.span(), mv$(res) );
- }
- else {
m_builder.set_result(node.span(), ::MIR::RValue::make_Tuple({}));
}
}