From 0dc4e9b46a3d7c270bd4691e007f38ac675d2035 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 31 Aug 2025 04:17:47 -0300 Subject: [PATCH 1/2] checker: add `T.typ` and `T.unaliased_typ` checking to `$match` (fix #25200) (#25202) --- vlib/v/checker/match.v | 4 +++ .../comptime_match_unaliased_typ_test.v | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 vlib/v/tests/comptime/comptime_match_unaliased_typ_test.v diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 8d33203ca7..90780494c1 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -104,6 +104,10 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { if c.comptime.inside_comptime_for && node.cond.field_name in ['name', 'typ'] { // hack: `typ` is just for bypass the error test, because we don't know it is a type match or a value match righ now comptime_match_cond_value = c.comptime.comptime_for_field_value.name + } else if mut node.cond.expr is ast.Ident + && node.cond.gkind_field in [.typ, .unaliased_typ] { + left_type := c.get_expr_type(node.cond.expr) + comptime_match_cond_value = c.table.type_to_str(left_type) } else { c.error('`${node.cond}` is not `\$for` field.name.', node.cond.pos) return ast.void_type diff --git a/vlib/v/tests/comptime/comptime_match_unaliased_typ_test.v b/vlib/v/tests/comptime/comptime_match_unaliased_typ_test.v new file mode 100644 index 0000000000..5dc9e74fd3 --- /dev/null +++ b/vlib/v/tests/comptime/comptime_match_unaliased_typ_test.v @@ -0,0 +1,35 @@ +fn check_unaliased[T](t T) bool { + $match T.unaliased_typ { + int { + return true + } + $else { + return false + } + } +} + +fn check_typ[T](t T) bool { + $match T.typ { + int { + return true + } + $else { + return false + } + } +} + +type FooInt = int + +fn test_main() { + assert check_unaliased(1) + assert !check_unaliased('') + assert !check_unaliased(1.2) + assert check_unaliased(FooInt(0)) + + assert check_typ(1) + assert !check_typ('') + assert !check_typ(1.2) + assert !check_typ(FooInt(0)) +} From d31aaecc42286a63a7a2e95b24d48a2e0bfbfda4 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sun, 31 Aug 2025 12:51:11 +0530 Subject: [PATCH 2/2] checker: add more checks for map.delete (fix #25204) (#25205) --- vlib/v/checker/fn.v | 13 +++++++------ vlib/v/checker/tests/map_delete.out | 29 +++++++++++++++++++++-------- vlib/v/checker/tests/map_delete.vv | 2 ++ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 3b2b3aa245..c484eb5a95 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -3213,14 +3213,15 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type_ ast } 'delete' { c.check_for_mut_receiver(mut node.left) - if node.args.len != 1 { + if node.args.len == 1 { + info := left_sym.info as ast.Map + arg_type := c.expr(mut node.args[0].expr) + c.check_expected_call_arg(arg_type, info.key_type, node.language, node.args[0]) or { + c.error('${err.msg()} in argument 1 to `Map.delete`', node.args[0].pos) + } + } else { c.error('expected 1 argument, but got ${node.args.len}', node.pos) } - info := left_sym.info as ast.Map - arg_type := c.expr(mut node.args[0].expr) - c.check_expected_call_arg(arg_type, info.key_type, node.language, node.args[0]) or { - c.error('${err.msg()} in argument 1 to `Map.delete`', node.args[0].pos) - } } else {} } diff --git a/vlib/v/checker/tests/map_delete.out b/vlib/v/checker/tests/map_delete.out index 7706f321ff..18ef09cbc7 100644 --- a/vlib/v/checker/tests/map_delete.out +++ b/vlib/v/checker/tests/map_delete.out @@ -12,16 +12,29 @@ vlib/v/checker/tests/map_delete.vv:6:4: error: expected 1 argument, but got 2 | ~~~~~~~~~~~~ 7 | m2 := { 8 | '1': 1 -vlib/v/checker/tests/map_delete.vv:6:11: error: cannot use `int literal` as `string` in argument 1 to `Map.delete` - 4 | } - 5 | m.delete(1) - 6 | m.delete(1, 2) - | ^ - 7 | m2 := { - 8 | '1': 1 vlib/v/checker/tests/map_delete.vv:10:2: error: `m2` is immutable, declare it with `mut` to make it mutable 8 | '1': 1 9 | } 10 | m2.delete('1') | ~~ - 11 | } + 11 | m.delete() + 12 | _ := m.delete() +vlib/v/checker/tests/map_delete.vv:11:4: error: expected 1 argument, but got 0 + 9 | } + 10 | m2.delete('1') + 11 | m.delete() + | ~~~~~~~~ + 12 | _ := m.delete() + 13 | } +vlib/v/checker/tests/map_delete.vv:12:9: error: expected 1 argument, but got 0 + 10 | m2.delete('1') + 11 | m.delete() + 12 | _ := m.delete() + | ~~~~~~~~ + 13 | } +vlib/v/checker/tests/map_delete.vv:12:4: error: assignment mismatch: 1 variable but `delete()` returns 0 values + 10 | m2.delete('1') + 11 | m.delete() + 12 | _ := m.delete() + | ~~ + 13 | } diff --git a/vlib/v/checker/tests/map_delete.vv b/vlib/v/checker/tests/map_delete.vv index c9cd093b90..3583557ce3 100644 --- a/vlib/v/checker/tests/map_delete.vv +++ b/vlib/v/checker/tests/map_delete.vv @@ -8,4 +8,6 @@ fn main() { '1': 1 } m2.delete('1') + m.delete() + _ := m.delete() }