match: implement exhaustive match for bool values (#7761)
							parent
							
								
									73f41f9a2a
								
							
						
					
					
						commit
						9ac237d9c0
					
				| 
						 | 
				
			
			@ -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,9 +3859,18 @@ 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 {
 | 
			
		||||
	if node.cond_type == table.bool_type {
 | 
			
		||||
		variants := ['true', 'false']
 | 
			
		||||
		for v in variants {
 | 
			
		||||
			if v !in branch_exprs {
 | 
			
		||||
				is_exhaustive = false
 | 
			
		||||
				unhandled << '`$v`'
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		match mut cond_type_sym.info {
 | 
			
		||||
			table.SumType {
 | 
			
		||||
			for v in type_sym.info.variants {
 | 
			
		||||
				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
 | 
			
		||||
| 
						 | 
				
			
			@ -3872,7 +3880,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
 | 
			
		|||
			}
 | 
			
		||||
			//
 | 
			
		||||
			table.Enum {
 | 
			
		||||
			for v in type_sym.info.vals {
 | 
			
		||||
				for v in cond_type_sym.info.vals {
 | 
			
		||||
					if v !in branch_exprs {
 | 
			
		||||
						is_exhaustive = false
 | 
			
		||||
						unhandled << '`.$v`'
 | 
			
		||||
| 
						 | 
				
			
			@ -3883,6 +3891,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
 | 
			
		|||
				is_exhaustive = false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	mut else_branch := node.branches[node.branches.len - 1]
 | 
			
		||||
	mut has_else := else_branch.is_else
 | 
			
		||||
	if !has_else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue