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:
parent
f6cc88fa69
commit
dee75fe970
@ -643,7 +643,7 @@ fn (mut c Checker) symmetric_check(left ast.Type, right ast.Type) bool {
|
||||
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{}
|
||||
sym := c.table.sym(typ)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 node.is_short_syntax {
|
||||
concrete_types := c.infer_generic_struct_init_concrete_types(node.typ,
|
||||
node)
|
||||
concrete_types := c.infer_struct_generic_types(node.typ, node)
|
||||
if concrete_types.len > 0 {
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user