mirror of
https://github.com/vlang/v.git
synced 2025-09-10 16:00:31 -04:00
checker: fix generic array method call with multi-types (#20237)
This commit is contained in:
parent
7a16a72cc5
commit
c0321c81a8
@ -1741,10 +1741,10 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||||||
} else if (left_sym.kind == .map || final_left_sym.kind == .map)
|
} else if (left_sym.kind == .map || final_left_sym.kind == .map)
|
||||||
&& method_name in ['clone', 'keys', 'values', 'move', 'delete'] {
|
&& method_name in ['clone', 'keys', 'values', 'move', 'delete'] {
|
||||||
if left_sym.kind == .map {
|
if left_sym.kind == .map {
|
||||||
return c.map_builtin_method_call(mut node, unwrapped_left_type, c.table.sym(unwrapped_left_type))
|
return c.map_builtin_method_call(mut node, left_type)
|
||||||
} else if left_sym.info is ast.Alias {
|
} else if left_sym.info is ast.Alias {
|
||||||
parent_type := c.unwrap_generic(left_sym.info.parent_type)
|
parent_type := left_sym.info.parent_type
|
||||||
return c.map_builtin_method_call(mut node, parent_type, c.table.final_sym(unwrapped_left_type))
|
return c.map_builtin_method_call(mut node, parent_type)
|
||||||
}
|
}
|
||||||
} else if left_sym.kind == .array && method_name in ['insert', 'prepend'] {
|
} else if left_sym.kind == .array && method_name in ['insert', 'prepend'] {
|
||||||
if method_name == 'insert' {
|
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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.Type, left_sym ast.TypeSymbol) ast.Type {
|
fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type_ ast.Type) ast.Type {
|
||||||
method_name := node.name
|
method_name := node.name
|
||||||
mut ret_type := ast.void_type
|
mut ret_type := ast.void_type
|
||||||
|
// resolve T
|
||||||
|
left_type := if c.table.final_sym(left_type_).kind == .any {
|
||||||
|
c.unwrap_generic(left_type_)
|
||||||
|
} else {
|
||||||
|
left_type_
|
||||||
|
}
|
||||||
|
left_sym := c.table.final_sym(left_type)
|
||||||
match method_name {
|
match method_name {
|
||||||
'clone', 'move' {
|
'clone', 'move' {
|
||||||
if node.args.len != 0 {
|
if node.args.len != 0 {
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
pub type EventListener[T] = fn (T) !
|
||||||
|
|
||||||
|
pub type Check[T] = fn (T) bool
|
||||||
|
|
||||||
|
pub struct EventController[T] {
|
||||||
|
mut:
|
||||||
|
id int
|
||||||
|
listeners map[int]EventListener[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut ec EventController[T]) generate_id() int {
|
||||||
|
return ec.id++
|
||||||
|
}
|
||||||
|
|
||||||
|
@[params]
|
||||||
|
pub struct EmitOptions {
|
||||||
|
pub:
|
||||||
|
error_handler ?fn (int, IError)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut ec EventController[T]) emit(e T, options EmitOptions) {
|
||||||
|
if ec.listeners.len == 1 {
|
||||||
|
f := ec.listeners.values()[0]
|
||||||
|
f(e) or {
|
||||||
|
if g := options.error_handler {
|
||||||
|
g(0, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo {}
|
||||||
|
|
||||||
|
struct Bar {}
|
||||||
|
|
||||||
|
fn test_generic_array_method_call_with_multi_types() {
|
||||||
|
foo := EventController[Foo]{}
|
||||||
|
println(foo)
|
||||||
|
assert foo.id == 0
|
||||||
|
bar := EventController[Bar]{}
|
||||||
|
println(bar)
|
||||||
|
assert bar.id == 0
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user