Skip to content

Commit a983760

Browse files
authored
checker: fix missing re-check of recursive generic function (fix #16962) (#17592)
1 parent 48a03a4 commit a983760

2 files changed

Lines changed: 56 additions & 3 deletions

File tree

vlib/v/checker/fn.v

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,18 +1598,27 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
15981598
arg_sym := c.table.sym(c.comptime_fields_default_type)
15991599
if arg_sym.kind == .array
16001600
&& c.table.sym(method.params[param_idx].typ).kind == .array {
1601-
c.table.register_fn_concrete_types(method.fkey(), [
1601+
if c.table.register_fn_concrete_types(method.fkey(), [
16021602
(arg_sym.info as ast.Array).elem_type,
16031603
])
1604+
{
1605+
c.need_recheck_generic_fns = true
1606+
}
16041607
} else {
1605-
c.table.register_fn_concrete_types(method.fkey(), [
1608+
if c.table.register_fn_concrete_types(method.fkey(), [
16061609
c.comptime_fields_default_type,
16071610
])
1611+
{
1612+
c.need_recheck_generic_fns = true
1613+
}
16081614
}
16091615
} else if c.inside_for_in_any_cond && method.params[param_idx].typ.has_flag(.generic) {
1610-
c.table.register_fn_concrete_types(method.fkey(), [
1616+
if c.table.register_fn_concrete_types(method.fkey(), [
16111617
c.for_in_any_val_type,
16121618
])
1619+
{
1620+
c.need_recheck_generic_fns = true
1621+
}
16131622
}
16141623
if no_type_promotion {
16151624
if got_arg_typ != exp_arg_typ {

vlib/v/tests/generic_struct_test.v

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
struct Test {}
2+
3+
fn (t Test) test[T](val T) {
4+
$for f in T.fields {
5+
value := val.$(f.name)
6+
$if f.is_option {
7+
$if f.typ is $Struct {
8+
_ := 1
9+
t.test(value)
10+
} $else $if f.typ is string {
11+
_ := 2
12+
} $else $if f.typ is ?string {
13+
_ := 3
14+
} $else {
15+
_ := 4
16+
}
17+
} $else {
18+
$if f.typ is $Struct {
19+
t.test(value)
20+
} $else $if f.typ is string {
21+
_ := 5
22+
}
23+
}
24+
}
25+
}
26+
27+
struct Bb {
28+
a ?string
29+
}
30+
31+
struct Cc {
32+
b Bb
33+
}
34+
35+
struct Aa[T] {
36+
a T
37+
}
38+
39+
fn test_main() {
40+
a := Aa[Cc]{}
41+
t := Test{}
42+
t.test(a)
43+
assert true
44+
}

0 commit comments

Comments
 (0)