1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: fix generic information is lost of the map built-in method call (fix #16077) (#16134)

This commit is contained in:
shove 2022-10-22 04:07:05 +08:00 committed by GitHub
parent ab78d5a7ba
commit e863191ff6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 2 deletions

View File

@ -1291,10 +1291,10 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
} else if (left_sym.kind == .map || final_left_sym.kind == .map)
&& method_name in ['clone', 'keys', 'values', 'move', 'delete'] {
if left_sym.kind == .map {
return c.map_builtin_method_call(mut node, left_type, left_sym)
return c.map_builtin_method_call(mut node, left_type, c.table.sym(left_type))
} else {
parent_type := (left_sym.info as ast.Alias).parent_type
return c.map_builtin_method_call(mut node, parent_type, final_left_sym)
return c.map_builtin_method_call(mut node, parent_type, c.table.final_sym(left_type))
}
} else if left_sym.kind == .array && method_name in ['insert', 'prepend'] {
if method_name == 'insert' {
@ -2085,6 +2085,12 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
c.table.find_or_register_array(info.value_type)
}
ret_type = ast.Type(typ)
if method_name == 'keys' && info.key_type.has_flag(.generic) {
ret_type = ret_type.set_flag(.generic)
}
if method_name == 'values' && info.value_type.has_flag(.generic) {
ret_type = ret_type.set_flag(.generic)
}
}
'delete' {
c.fail_if_immutable(node.left)

View File

@ -0,0 +1,27 @@
fn call_key_is_generic<T>(v T) {
a := map[T]u8{}
_ := a.keys().filter(it == v)
}
fn call_value_is_generic<T>(v T) {
a := map[u8]T{}
_ := a.values().filter(it == v)
}
fn call_all_is_generic_keys_method<T, U>(v T) {
a := map[T]U{}
_ := a.keys().filter(it == v)
}
fn call_all_is_generic_values_method<T, U>(v U) {
a := map[T]U{}
_ := a.values().filter(it == v)
}
fn test_call_has_generic() {
call_key_is_generic<int>(1)
call_value_is_generic<string>('')
call_all_is_generic_keys_method<int, string>(1)
call_all_is_generic_values_method<int, string>('')
assert true
}