diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 62604007fd..b8edca6bb1 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -6085,6 +6085,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym // parser failed, stop checking return } + expr_type_sym := c.table.get_type_symbol(expr_type) if cond_type_sym.kind == .interface_ { // TODO // This generates a memory issue with TCC @@ -6094,7 +6095,6 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym expr_pos := expr.position() if c.type_implements(expr_type, c.expected_type, expr_pos) { if !expr_type.is_ptr() && !expr_type.is_pointer() && !c.inside_unsafe { - expr_type_sym := c.table.get_type_symbol(expr_type) if expr_type_sym.kind != .interface_ { c.mark_as_referenced(mut &branch.exprs[k], true) } @@ -6106,10 +6106,14 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym expect_str := c.table.type_to_str(node.cond_type) c.error('`$expect_str` has no variant `$expr_str`', expr.position()) } + } else if cond_type_sym.info is ast.Alias && expr_type_sym.info is ast.Struct { + expr_str := c.table.type_to_str(expr_type) + expect_str := c.table.type_to_str(node.cond_type) + c.error('cannot match alias type `$expect_str` with `$expr_str`', expr.position()) } else if !c.check_types(expr_type, node.cond_type) { expr_str := c.table.type_to_str(expr_type) expect_str := c.table.type_to_str(node.cond_type) - c.error('cannot match `$expr_str` with `$expect_str` condition', expr.position()) + c.error('cannot match `$expect_str` with `$expr_str`', expr.position()) } branch_exprs[key] = val + 1 } diff --git a/vlib/v/checker/tests/match_alias_type_err.out b/vlib/v/checker/tests/match_alias_type_err.out new file mode 100644 index 0000000000..49ddf1f3e3 --- /dev/null +++ b/vlib/v/checker/tests/match_alias_type_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/match_alias_type_err.vv:13:3: error: cannot match alias type `Stmt` with `SelectStmt` + 11 | + 12 | match stmt { + 13 | SelectStmt { panic('select') } + | ~~~~~~~~~~ + 14 | else { /* why? */ } + 15 | } diff --git a/vlib/v/checker/tests/match_alias_type_err.vv b/vlib/v/checker/tests/match_alias_type_err.vv new file mode 100644 index 0000000000..2673231b19 --- /dev/null +++ b/vlib/v/checker/tests/match_alias_type_err.vv @@ -0,0 +1,16 @@ +type Stmt = SelectStmt + +struct SelectStmt {} + +fn parse(sql string) Stmt { + return SelectStmt{} +} + +fn main() { + stmt := parse('select 123') + + match stmt { + SelectStmt { panic('select') } + else { /* why? */ } + } +} diff --git a/vlib/v/checker/tests/match_expr_and_expected_type_error.out b/vlib/v/checker/tests/match_expr_and_expected_type_error.out index 2d4089d19d..e42355f740 100644 --- a/vlib/v/checker/tests/match_expr_and_expected_type_error.out +++ b/vlib/v/checker/tests/match_expr_and_expected_type_error.out @@ -1,11 +1,11 @@ -vlib/v/checker/tests/match_expr_and_expected_type_error.vv:3:3: error: cannot match `string` with `rune` condition +vlib/v/checker/tests/match_expr_and_expected_type_error.vv:3:3: error: cannot match `rune` with `string` 1 | ch := `a` 2 | match ch { 3 | 'a' {} | ~~~ 4 | else {} 5 | } -vlib/v/checker/tests/match_expr_and_expected_type_error.vv:9:3: error: cannot match `string` with `int` condition +vlib/v/checker/tests/match_expr_and_expected_type_error.vv:9:3: error: cannot match `int` with `string` 7 | i := 123 8 | match i { 9 | 'a' {} diff --git a/vlib/v/checker/tests/match_undefined_cond.out b/vlib/v/checker/tests/match_undefined_cond.out index ca813c40ce..ddfed08da6 100644 --- a/vlib/v/checker/tests/match_undefined_cond.out +++ b/vlib/v/checker/tests/match_undefined_cond.out @@ -5,14 +5,14 @@ vlib/v/checker/tests/match_undefined_cond.vv:4:15: error: undefined ident: `Asd` | ~~~ 5 | 1 { 'foo' } 6 | 2 { 'test' } -vlib/v/checker/tests/match_undefined_cond.vv:5:3: error: cannot match `int literal` with `void` condition +vlib/v/checker/tests/match_undefined_cond.vv:5:3: error: cannot match `void` with `int literal` 3 | fn main() { 4 | res := match Asd { 5 | 1 { 'foo' } | ^ 6 | 2 { 'test' } 7 | else { '' } -vlib/v/checker/tests/match_undefined_cond.vv:6:3: error: cannot match `int literal` with `void` condition +vlib/v/checker/tests/match_undefined_cond.vv:6:3: error: cannot match `void` with `int literal` 4 | res := match Asd { 5 | 1 { 'foo' } 6 | 2 { 'test' }