match: implement exhaustive match for bool values (#7761)

pull/7779/head
clubby789 2021-01-01 11:28:23 +00:00 committed by GitHub
parent 73f41f9a2a
commit 9ac237d9c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 21 deletions

View File

@ -3673,11 +3673,10 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
return ret_type
}
fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol) {
fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeSymbol) {
// branch_exprs is a histogram of how many times
// an expr was used in the match
mut branch_exprs := map[string]int{}
cond_type_sym := c.table.get_type_symbol(node.cond_type)
for branch_i, _ in node.branches {
mut branch := node.branches[branch_i]
mut expr_types := []ast.Type{}
@ -3860,27 +3859,37 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
// by listing all variants or values
mut is_exhaustive := true
mut unhandled := []string{}
match mut type_sym.info {
table.SumType {
for v in type_sym.info.variants {
v_str := c.table.type_to_str(v)
if v_str !in branch_exprs {
is_exhaustive = false
unhandled << '`$v_str`'
}
if node.cond_type == table.bool_type {
variants := ['true', 'false']
for v in variants {
if v !in branch_exprs {
is_exhaustive = false
unhandled << '`$v`'
}
}
//
table.Enum {
for v in type_sym.info.vals {
if v !in branch_exprs {
is_exhaustive = false
unhandled << '`.$v`'
} else {
match mut cond_type_sym.info {
table.SumType {
for v in cond_type_sym.info.variants {
v_str := c.table.type_to_str(v)
if v_str !in branch_exprs {
is_exhaustive = false
unhandled << '`$v_str`'
}
}
}
}
else {
is_exhaustive = false
//
table.Enum {
for v in cond_type_sym.info.vals {
if v !in branch_exprs {
is_exhaustive = false
unhandled << '`.$v`'
}
}
}
else {
is_exhaustive = false
}
}
}
mut else_branch := node.branches[node.branches.len - 1]

View File

@ -21,7 +21,6 @@ fn test_assign_multi_expr_func() {
g, h := match true {
true { multireturner(0, 'good') }
false { multireturner(100, 'bad') }
else { multireturner(200, 'bad') }
}
assert g == 1
assert h == 'good'
@ -36,7 +35,6 @@ fn test_assign_multi_expr() {
a,b,c := match false {
true { 1,2,3 }
false { 4,5,6 }
else { 7,8,9 }
}
assert a == 4
assert b == 5