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 {
|
pub struct Checker {
|
||||||
pref &pref.Preferences // Preferences shared from V struct
|
pref &pref.Preferences // Preferences shared from V struct
|
||||||
pub mut:
|
pub mut:
|
||||||
table &ast.Table
|
table &ast.Table
|
||||||
file &ast.File = 0
|
file &ast.File = 0
|
||||||
nr_errors int
|
nr_errors int
|
||||||
nr_warnings int
|
nr_warnings int
|
||||||
nr_notices int
|
nr_notices int
|
||||||
errors []errors.Error
|
errors []errors.Error
|
||||||
warnings []errors.Warning
|
warnings []errors.Warning
|
||||||
notices []errors.Notice
|
notices []errors.Notice
|
||||||
error_lines []int // to avoid printing multiple errors for the same line
|
error_lines []int // to avoid printing multiple errors for the same line
|
||||||
expected_type ast.Type
|
expected_type ast.Type
|
||||||
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
|
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
|
||||||
mod string // current module name
|
expected_expr_type ast.Type // if/match is_expr: expected_type
|
||||||
const_decl string
|
mod string // current module name
|
||||||
const_deps []string
|
const_decl string
|
||||||
const_names []string
|
const_deps []string
|
||||||
global_names []string
|
const_names []string
|
||||||
locked_names []string // vars that are currently locked
|
global_names []string
|
||||||
rlocked_names []string // vars that are currently read-locked
|
locked_names []string // vars that are currently locked
|
||||||
in_for_count int // if checker is currently in a for loop
|
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
|
// 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.
|
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
|
returns bool
|
||||||
|
@ -3835,7 +3836,11 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||||
// with this value.
|
// with this value.
|
||||||
pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
||||||
mut typ_idx := if node.enum_name == '' {
|
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 {
|
} else {
|
||||||
c.table.find_type_idx(node.enum_name)
|
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) {`.',
|
c.error('unnecessary `()` in `match` condition, use `match expr {` instead of `match (expr) {`.',
|
||||||
node.cond.pos)
|
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)
|
cond_type := c.expr(node.cond)
|
||||||
// we setting this here rather than at the end of the method
|
// we setting this here rather than at the end of the method
|
||||||
// since it is used in c.match_exprs() it saves checking twice
|
// 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