Compare commits

...

2 commits

Author SHA1 Message Date
Swastik Baranwal
d31aaecc42
checker: add more checks for map.delete (fix #25204) (#25205)
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
2025-08-31 10:21:11 +03:00
Felipe Pena
0dc4e9b46a
checker: add T.typ and T.unaliased_typ checking to $match (fix #25200) (#25202) 2025-08-31 10:17:47 +03:00
5 changed files with 69 additions and 14 deletions

View file

@ -3213,14 +3213,15 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type_ ast
} }
'delete' { 'delete' {
c.check_for_mut_receiver(mut node.left) 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) 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 {} else {}
} }

View file

@ -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'] { 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 // 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 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 { } else {
c.error('`${node.cond}` is not `\$for` field.name.', node.cond.pos) c.error('`${node.cond}` is not `\$for` field.name.', node.cond.pos)
return ast.void_type return ast.void_type

View file

@ -12,16 +12,29 @@ vlib/v/checker/tests/map_delete.vv:6:4: error: expected 1 argument, but got 2
| ~~~~~~~~~~~~ | ~~~~~~~~~~~~
7 | m2 := { 7 | m2 := {
8 | '1': 1 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 vlib/v/checker/tests/map_delete.vv:10:2: error: `m2` is immutable, declare it with `mut` to make it mutable
8 | '1': 1 8 | '1': 1
9 | } 9 | }
10 | m2.delete('1') 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 | }

View file

@ -8,4 +8,6 @@ fn main() {
'1': 1 '1': 1
} }
m2.delete('1') m2.delete('1')
m.delete()
_ := m.delete()
} }

View file

@ -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))
}