Skip to content

Commit c0321c8

Browse files
authored
checker: fix generic array method call with multi-types (#20237)
1 parent 7a16a72 commit c0321c8

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

vlib/v/checker/fn.v

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,10 +1741,10 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
17411741
} else if (left_sym.kind == .map || final_left_sym.kind == .map)
17421742
&& method_name in ['clone', 'keys', 'values', 'move', 'delete'] {
17431743
if left_sym.kind == .map {
1744-
return c.map_builtin_method_call(mut node, unwrapped_left_type, c.table.sym(unwrapped_left_type))
1744+
return c.map_builtin_method_call(mut node, left_type)
17451745
} else if left_sym.info is ast.Alias {
1746-
parent_type := c.unwrap_generic(left_sym.info.parent_type)
1747-
return c.map_builtin_method_call(mut node, parent_type, c.table.final_sym(unwrapped_left_type))
1746+
parent_type := left_sym.info.parent_type
1747+
return c.map_builtin_method_call(mut node, parent_type)
17481748
}
17491749
} else if left_sym.kind == .array && method_name in ['insert', 'prepend'] {
17501750
if method_name == 'insert' {
@@ -2652,9 +2652,16 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, node ast
26522652
}
26532653
}
26542654

2655-
fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.Type, left_sym ast.TypeSymbol) ast.Type {
2655+
fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type_ ast.Type) ast.Type {
26562656
method_name := node.name
26572657
mut ret_type := ast.void_type
2658+
// resolve T
2659+
left_type := if c.table.final_sym(left_type_).kind == .any {
2660+
c.unwrap_generic(left_type_)
2661+
} else {
2662+
left_type_
2663+
}
2664+
left_sym := c.table.final_sym(left_type)
26582665
match method_name {
26592666
'clone', 'move' {
26602667
if node.args.len != 0 {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
pub type EventListener[T] = fn (T) !
2+
3+
pub type Check[T] = fn (T) bool
4+
5+
pub struct EventController[T] {
6+
mut:
7+
id int
8+
listeners map[int]EventListener[T]
9+
}
10+
11+
fn (mut ec EventController[T]) generate_id() int {
12+
return ec.id++
13+
}
14+
15+
@[params]
16+
pub struct EmitOptions {
17+
pub:
18+
error_handler ?fn (int, IError)
19+
}
20+
21+
pub fn (mut ec EventController[T]) emit(e T, options EmitOptions) {
22+
if ec.listeners.len == 1 {
23+
f := ec.listeners.values()[0]
24+
f(e) or {
25+
if g := options.error_handler {
26+
g(0, err)
27+
}
28+
}
29+
return
30+
}
31+
}
32+
33+
struct Foo {}
34+
35+
struct Bar {}
36+
37+
fn test_generic_array_method_call_with_multi_types() {
38+
foo := EventController[Foo]{}
39+
println(foo)
40+
assert foo.id == 0
41+
bar := EventController[Bar]{}
42+
println(bar)
43+
assert bar.id == 0
44+
}

0 commit comments

Comments
 (0)