checker: fix match expr with enum type value (#13683)
							parent
							
								
									17fcc788f2
								
							
						
					
					
						commit
						cea3149369
					
				|  | @ -57,25 +57,26 @@ fn all_valid_comptime_idents() []string { | |||
| pub struct Checker { | ||||
| 	pref &pref.Preferences // Preferences shared from V struct
 | ||||
| pub mut: | ||||
| 	table            &ast.Table | ||||
| 	file             &ast.File = 0 | ||||
| 	nr_errors        int | ||||
| 	nr_warnings      int | ||||
| 	nr_notices       int | ||||
| 	errors           []errors.Error | ||||
| 	warnings         []errors.Warning | ||||
| 	notices          []errors.Notice | ||||
| 	error_lines      []int // to avoid printing multiple errors for the same line
 | ||||
| 	expected_type    ast.Type | ||||
| 	expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
 | ||||
| 	mod              string   // current module name
 | ||||
| 	const_decl       string | ||||
| 	const_deps       []string | ||||
| 	const_names      []string | ||||
| 	global_names     []string | ||||
| 	locked_names     []string // vars that are currently locked
 | ||||
| 	rlocked_names    []string // vars that are currently read-locked
 | ||||
| 	in_for_count     int      // if checker is currently in a for loop
 | ||||
| 	table              &ast.Table | ||||
| 	file               &ast.File = 0 | ||||
| 	nr_errors          int | ||||
| 	nr_warnings        int | ||||
| 	nr_notices         int | ||||
| 	errors             []errors.Error | ||||
| 	warnings           []errors.Warning | ||||
| 	notices            []errors.Notice | ||||
| 	error_lines        []int // to avoid printing multiple errors for the same line
 | ||||
| 	expected_type      ast.Type | ||||
| 	expected_or_type   ast.Type // fn() or { 'this type' } eg. string. expected or block type
 | ||||
| 	expected_expr_type ast.Type // if/match is_expr: expected_type
 | ||||
| 	mod                string   // current module name
 | ||||
| 	const_decl         string | ||||
| 	const_deps         []string | ||||
| 	const_names        []string | ||||
| 	global_names       []string | ||||
| 	locked_names       []string // vars that are currently locked
 | ||||
| 	rlocked_names      []string // vars that are currently read-locked
 | ||||
| 	in_for_count       int      // if checker is currently in a for loop
 | ||||
| 	// checked_ident  string // to avoid infinite checker loops
 | ||||
| 	should_abort              bool // when too many errors/warnings/notices are accumulated, .should_abort becomes true. It is checked in statement/expression loops, so the checker can return early, instead of wasting time.
 | ||||
| 	returns                   bool | ||||
|  | @ -3835,7 +3836,11 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { | |||
| // with this value.
 | ||||
| pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type { | ||||
| 	mut typ_idx := if node.enum_name == '' { | ||||
| 		c.expected_type.idx() | ||||
| 		if c.expected_type == ast.void_type && c.expected_expr_type != ast.void_type { | ||||
| 			c.expected_expr_type.idx() | ||||
| 		} else { | ||||
| 			c.expected_type.idx() | ||||
| 		} | ||||
| 	} else { | ||||
| 		c.table.find_type_idx(node.enum_name) | ||||
| 	} | ||||
|  |  | |||
|  | @ -13,6 +13,12 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { | |||
| 		c.error('unnecessary `()` in `match` condition, use `match expr {` instead of `match (expr) {`.', | ||||
| 			node.cond.pos) | ||||
| 	} | ||||
| 	if node.is_expr { | ||||
| 		c.expected_expr_type = c.expected_type | ||||
| 		defer { | ||||
| 			c.expected_expr_type = ast.void_type | ||||
| 		} | ||||
| 	} | ||||
| 	cond_type := c.expr(node.cond) | ||||
| 	// we setting this here rather than at the end of the method
 | ||||
| 	// since it is used in c.match_exprs() it saves checking twice
 | ||||
|  |  | |||
|  | @ -0,0 +1,24 @@ | |||
| enum Foo { | ||||
| 	a | ||||
| 	b | ||||
| 	c | ||||
| } | ||||
| 
 | ||||
| fn get() Foo { | ||||
| 	return .a | ||||
| } | ||||
| 
 | ||||
| fn foo(f Foo) string { | ||||
| 	println(f) | ||||
| 	return '$f' | ||||
| } | ||||
| 
 | ||||
| fn test_match_expr_with_enum() { | ||||
| 	ret := foo(match get() { | ||||
| 		.a { .b } | ||||
| 		.b { .c } | ||||
| 		.c { .a } | ||||
| 	}) | ||||
| 	println(ret) | ||||
| 	assert ret == 'b' | ||||
| } | ||||
		Loading…
	
		Reference in New Issue