diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-14 09:40:11 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-14 09:40:11 +0800 |
commit | f71f82f0f09e200906ffe0632ef4817c672c7fd4 (patch) | |
tree | 81e6cfbf7db68d369dd4ef9d588966a0686e7298 /src/mir/from_hir_match.cpp | |
parent | b42d3a186494b1ce36133cf5630405ea013778c2 (diff) | |
download | mrust-f71f82f0f09e200906ffe0632ef4817c672c7fd4.tar.gz |
HIR Gen Match - Handle common enum patterns
Diffstat (limited to 'src/mir/from_hir_match.cpp')
-rw-r--r-- | src/mir/from_hir_match.cpp | 44 |
1 files changed, 38 insertions, 6 deletions
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="<<branch); + } + ), + (Terminal, + //if( e == arm_index ) // Wut? How would this happen? Exact duplicate pattern + // return ; + BUG(sp, "Duplicate terminal - Existing goes to arm " << e << ", new goes to arm " << e ); + ) + ) + branch = Branch::make_Terminal(arm_index); + }); } // `and_then` - Closure called after processing the final rule void populate_tree_from_rule(const Span& sp, const PatternRule* first_rule, unsigned int rule_count, ::std::function<void(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); }); } |