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