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

checker: perfect infer_struct_generic_types() (#16524)

This commit is contained in:
yuyi 2022-11-25 01:30:02 +08:00 committed by GitHub
parent f6cc88fa69
commit dee75fe970
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 3 deletions

View File

@ -643,7 +643,7 @@ fn (mut c Checker) symmetric_check(left ast.Type, right ast.Type) bool {
return c.check_basic(left, right) return c.check_basic(left, right)
} }
fn (mut c Checker) infer_generic_struct_init_concrete_types(typ ast.Type, node ast.StructInit) []ast.Type { fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit) []ast.Type {
mut concrete_types := []ast.Type{} mut concrete_types := []ast.Type{}
sym := c.table.sym(typ) sym := c.table.sym(typ)
if sym.info is ast.Struct { if sym.info is ast.Struct {
@ -752,6 +752,39 @@ fn (mut c Checker) infer_generic_struct_init_concrete_types(typ ast.Type, node a
} }
} }
} }
} else if field_sym.kind == .function {
for t in node.fields {
if ft.name == t.name {
init_sym := c.table.sym(t.typ)
if init_sym.kind == .function {
init_type_func := (init_sym.info as ast.FnType).func
field_type_func := (field_sym.info as ast.FnType).func
if field_type_func.params.len == init_type_func.params.len {
for n, fn_param in field_type_func.params {
if fn_param.typ.has_flag(.generic)
&& c.table.sym(fn_param.typ).name == gt_name {
mut arg_typ := init_type_func.params[n].typ
if fn_param.typ.nr_muls() > 0 && arg_typ.nr_muls() > 0 {
arg_typ = arg_typ.set_nr_muls(0)
}
concrete_types << arg_typ
continue gname
}
}
if field_type_func.return_type.has_flag(.generic)
&& c.table.sym(field_type_func.return_type).name == gt_name {
mut ret_typ := init_type_func.return_type
if field_type_func.return_type.nr_muls() > 0
&& ret_typ.nr_muls() > 0 {
ret_typ = ret_typ.set_nr_muls(0)
}
concrete_types << ret_typ
continue gname
}
}
}
}
}
} }
} }
} }

View File

@ -256,8 +256,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
} }
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0 { if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0 {
if node.is_short_syntax { if node.is_short_syntax {
concrete_types := c.infer_generic_struct_init_concrete_types(node.typ, concrete_types := c.infer_struct_generic_types(node.typ, node)
node)
if concrete_types.len > 0 { if concrete_types.len > 0 {
generic_names := struct_sym.info.generic_types.map(c.table.sym(it).name) generic_names := struct_sym.info.generic_types.map(c.table.sym(it).name)
node.typ = c.table.unwrap_generic_type(node.typ, generic_names, concrete_types) node.typ = c.table.unwrap_generic_type(node.typ, generic_names, concrete_types)