From f71f82f0f09e200906ffe0632ef4817c672c7fd4 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 14 Aug 2016 09:40:11 +0800 Subject: HIR Gen Match - Handle common enum patterns --- src/mir/from_hir_match.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) (limited to 'src/mir/from_hir_match.cpp') diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index b87e149d..b25584c7 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -563,7 +563,27 @@ struct DecisionTreeNode DecisionTreeNode clone() const; void populate_tree_from_rule(const Span& sp, unsigned int arm_index, const PatternRule* first_rule, unsigned int rule_count) { - populate_tree_from_rule(sp, first_rule, rule_count, [arm_index](auto& branch){ branch = Branch::make_Terminal(arm_index); }); + populate_tree_from_rule(sp, first_rule, rule_count, [sp,arm_index](auto& branch){ + TU_MATCHA( (branch), (e), + (Unset, + // Good + ), + (Subtree, + if( e->m_branches.is_Unset() && e->m_default.is_Unset() ) { + // Good. + } + else { + BUG(sp, "Duplicate terminal - branch="< and_then); @@ -687,6 +707,7 @@ void MIR_LowerHIR_Match_DecisionTree( MirBuilder& builder, MirConverter& conv, : for( const auto& arm_rule : arm_rules ) { auto arm_idx = arm_rule.arm_idx; + DEBUG("(" << arm_idx << ", " << arm_rule.pat_idx << "): " << arm_rule.m_rules); root_node.populate_tree_from_rule( node.m_arms[arm_idx].m_code->span(), arm_idx, arm_rule.m_rules.data(), arm_rule.m_rules.size() ); } DEBUG("root_node = " << root_node); @@ -1208,9 +1229,12 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule } } else TU_IFLET( Branch, m_default, Subtree, be, - assert( be ); - assert(rule_count > 1); - be->populate_tree_from_rule(sp, first_rule+1, rule_count-1, and_then); + if( rule_count == 1 ) { + and_then( m_default ); + } + else { + be->populate_tree_from_rule(sp, first_rule+1, rule_count-1, and_then); + } ) else { // NOTE: All lists processed as part of the same tree should be the same length @@ -1244,8 +1268,16 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule if( e.sub_rules.size() > 0 && rule_count > 1 ) { subtree.populate_tree_from_rule(sp, e.sub_rules.data(), e.sub_rules.size(), [&](auto& branch){ - ASSERT_BUG(sp, branch.is_Unset(), "Duplicate terminator"); - branch = new_branch_subtree(rule.field_path); + TU_MATCH_DEF(Branch, (branch), (be), + ( + BUG(sp, "Duplicate terminator"); + ), + (Unset, + branch = new_branch_subtree(rule.field_path); + ), + (Subtree, + ) + ) branch.as_Subtree()->populate_tree_from_rule(sp, first_rule+1, rule_count-1, and_then); }); } -- cgit v1.2.3