summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mir/from_hir.cpp5
-rw-r--r--src/mir/from_hir.hpp1
-rw-r--r--src/mir/mir_builder.cpp19
3 files changed, 24 insertions, 1 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index a281cbaa..c6d9bcd3 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -378,7 +378,10 @@ namespace {
if( node.m_arms.size() == 0 ) {
// Nothing
- TODO(node.span(), "Handle zero-arm match - can only match over ! or similar");
+ //const auto& ty = node.m_value->m_res_type;
+ // TODO: Ensure that the type is a zero-variant enum or !
+ m_builder.end_split_arm_early(node.span());
+ m_builder.end_block( ::MIR::Terminator::make_Diverge({}) );
}
else if( node.m_arms.size() == 1 && node.m_arms[0].m_patterns.size() == 1 && ! node.m_arms[0].m_cond ) {
// - Shortcut: Single-arm match
diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp
index c915cfcc..39890bbf 100644
--- a/src/mir/from_hir.hpp
+++ b/src/mir/from_hir.hpp
@@ -167,6 +167,7 @@ public:
void terminate_scope(const Span& sp, ScopeHandle );
void terminate_scope_early(const Span& sp, const ScopeHandle& );
void end_split_arm(const Span& sp, const ScopeHandle& , bool reachable);
+ void end_split_arm_early(const Span& sp);
const ScopeHandle& fcn_scope() const {
return m_fcn_scope;
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index f4f9db7e..c5564045 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -480,6 +480,25 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
// TODO: Undo moves from within the other scope
sd_split.arms.push_back( {} );
}
+void MirBuilder::end_split_arm_early(const Span& sp)
+{
+ // Terminate all scopes until a split is found.
+ while( ! m_scope_stack.empty() && ! m_scopes.at( m_scope_stack.back() ).data.is_Split() )
+ {
+ auto& scope_def = m_scopes[m_scope_stack.back()];
+ // Fully drop the scope
+ drop_scope_values(scope_def);
+ m_scope_stack.pop_back();
+ complete_scope(scope_def);
+ }
+
+ if( !m_scope_stack.empty() )
+ {
+ auto& sd = m_scopes[ m_scope_stack.back() ];
+ auto& sd_split = sd.data.as_Split();
+ sd_split.arms.back().has_early_terminated = true;
+ }
+}
void MirBuilder::complete_scope(ScopeDef& sd)
{
sd.complete = true;