Skip to content

Commit f6336fc

Browse files
authored
cgen: fix passing sumtype child to generic function taking sumtype parent (fix #25660) (#25664)
1 parent b45f2b6 commit f6336fc

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

vlib/v/gen/c/fn.v

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,6 +2411,40 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
24112411
}
24122412
}
24132413
}
2414+
if node.is_method {
2415+
left_sym := g.table.sym(node.left_type)
2416+
if left_sym.info is ast.Struct && left_sym.info.generic_types.len > 0
2417+
&& left_sym.info.concrete_types.len > 0 {
2418+
base_type_idx := g.table.find_type_idx(left_sym.name.all_before('['))
2419+
mut func := ast.Fn{}
2420+
mut found := false
2421+
for {
2422+
if base_type_idx > 0 {
2423+
base_sym := g.table.sym(ast.idx_to_type(base_type_idx))
2424+
if base_func := g.table.find_method(base_sym, node.name) {
2425+
func = base_func
2426+
found = true
2427+
break
2428+
}
2429+
}
2430+
if base_func := g.table.find_method(left_sym, node.name) {
2431+
func = base_func
2432+
found = true
2433+
}
2434+
break
2435+
}
2436+
if found && func.generic_names.len > 0 {
2437+
for i in 0 .. expected_types.len {
2438+
mut muttable := unsafe { &ast.Table(g.table) }
2439+
if utyp := muttable.convert_generic_type(node.expected_arg_types[i],
2440+
func.generic_names, left_sym.info.concrete_types)
2441+
{
2442+
expected_types[i] = utyp
2443+
}
2444+
}
2445+
}
2446+
}
2447+
}
24142448
// only v variadic, C variadic args will be appended like normal args
24152449
is_variadic := node.language == .v && node.is_variadic && expected_types.len > 0
24162450
&& expected_types.last().has_flag(.variadic)

vlib/v/tests/generics/generic_array_of_sumtype_push_test.v

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,31 @@ fn test_generic_array_of_sumtype_push() {
1717
assert ret2.len == 1
1818
assert ret2[0] == SumType('hello')
1919
}
20+
21+
struct EventA {
22+
a u32
23+
}
24+
25+
struct EventB {
26+
b u32
27+
}
28+
29+
type Event = EventA | EventB
30+
31+
struct Queue[T] {
32+
mut:
33+
data []T
34+
}
35+
36+
fn (mut q Queue[T]) push(val T) {
37+
q.data << val
38+
}
39+
40+
fn test_generic_queue_sumtype_structs() {
41+
mut queue := Queue[Event]{}
42+
queue.push(EventA{ a: 10 })
43+
assert queue.data.len == 1
44+
assert queue.data[0] == Event(EventA{
45+
a: 10
46+
})
47+
}

0 commit comments

Comments
 (0)