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

checker: fix missing re-check of recursive generic function (fix #16962) (#17592)

This commit is contained in:
Felipe Pena 2023-03-11 06:57:41 -03:00 committed by GitHub
parent 48a03a4874
commit a98376025e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 3 deletions

View File

@ -1598,18 +1598,27 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
arg_sym := c.table.sym(c.comptime_fields_default_type) arg_sym := c.table.sym(c.comptime_fields_default_type)
if arg_sym.kind == .array if arg_sym.kind == .array
&& c.table.sym(method.params[param_idx].typ).kind == .array { && c.table.sym(method.params[param_idx].typ).kind == .array {
c.table.register_fn_concrete_types(method.fkey(), [ if c.table.register_fn_concrete_types(method.fkey(), [
(arg_sym.info as ast.Array).elem_type, (arg_sym.info as ast.Array).elem_type,
]) ])
{
c.need_recheck_generic_fns = true
}
} else { } else {
c.table.register_fn_concrete_types(method.fkey(), [ if c.table.register_fn_concrete_types(method.fkey(), [
c.comptime_fields_default_type, c.comptime_fields_default_type,
]) ])
{
c.need_recheck_generic_fns = true
}
} }
} else if c.inside_for_in_any_cond && method.params[param_idx].typ.has_flag(.generic) { } else if c.inside_for_in_any_cond && method.params[param_idx].typ.has_flag(.generic) {
c.table.register_fn_concrete_types(method.fkey(), [ if c.table.register_fn_concrete_types(method.fkey(), [
c.for_in_any_val_type, c.for_in_any_val_type,
]) ])
{
c.need_recheck_generic_fns = true
}
} }
if no_type_promotion { if no_type_promotion {
if got_arg_typ != exp_arg_typ { if got_arg_typ != exp_arg_typ {

View File

@ -0,0 +1,44 @@
struct Test {}
fn (t Test) test[T](val T) {
$for f in T.fields {
value := val.$(f.name)
$if f.is_option {
$if f.typ is $Struct {
_ := 1
t.test(value)
} $else $if f.typ is string {
_ := 2
} $else $if f.typ is ?string {
_ := 3
} $else {
_ := 4
}
} $else {
$if f.typ is $Struct {
t.test(value)
} $else $if f.typ is string {
_ := 5
}
}
}
}
struct Bb {
a ?string
}
struct Cc {
b Bb
}
struct Aa[T] {
a T
}
fn test_main() {
a := Aa[Cc]{}
t := Test{}
t.test(a)
assert true
}