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

checker: clean up infer_struct_generic_types() and infer_fn_generic_types() (#17668)

This commit is contained in:
yuyi
2023-03-18 04:46:56 +08:00
committed by GitHub
parent 9e7aeec215
commit 24ea00da0c

View File

@@ -676,25 +676,22 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
}
}
}
if field_sym.kind == .array {
if field_sym.info is ast.Array {
for t in node.fields {
if ft.name == t.name {
init_sym := c.table.sym(t.typ)
if init_sym.kind == .array {
mut init_elem_info := init_sym.info as ast.Array
mut field_elem_info := field_sym.info as ast.Array
mut init_elem_sym := c.table.sym(init_elem_info.elem_type)
mut field_elem_sym := c.table.sym(field_elem_info.elem_type)
if init_sym.info is ast.Array {
mut init_elem_typ, mut field_elem_typ := init_sym.info.elem_type, field_sym.info.elem_type
mut init_elem_sym, mut field_elem_sym := c.table.sym(init_elem_typ), c.table.sym(field_elem_typ)
for {
if init_elem_sym.kind == .array && field_elem_sym.kind == .array {
init_elem_info = init_elem_sym.info as ast.Array
init_elem_sym = c.table.sym(init_elem_info.elem_type)
field_elem_info = field_elem_sym.info as ast.Array
field_elem_sym = c.table.sym(field_elem_info.elem_type)
if mut init_elem_sym.info is ast.Array
&& mut field_elem_sym.info is ast.Array {
init_elem_typ, field_elem_typ = init_elem_sym.info.elem_type, field_elem_sym.info.elem_type
init_elem_sym, field_elem_sym = c.table.sym(init_elem_typ), c.table.sym(field_elem_typ)
} else {
if field_elem_sym.name == gt_name {
mut elem_typ := init_elem_info.elem_type
if field_elem_info.elem_type.nr_muls() > 0
mut elem_typ := init_elem_typ
if field_elem_typ.nr_muls() > 0
&& elem_typ.nr_muls() > 0 {
elem_typ = elem_typ.set_nr_muls(0)
}
@@ -707,26 +704,22 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
}
}
}
} else if field_sym.kind == .array_fixed {
} else if field_sym.info is ast.ArrayFixed {
for t in node.fields {
if ft.name == t.name {
init_sym := c.table.sym(t.typ)
if init_sym.kind == .array_fixed {
mut init_elem_info := init_sym.info as ast.ArrayFixed
mut field_elem_info := field_sym.info as ast.ArrayFixed
mut init_elem_sym := c.table.sym(init_elem_info.elem_type)
mut field_elem_sym := c.table.sym(field_elem_info.elem_type)
if init_sym.info is ast.ArrayFixed {
mut init_elem_typ, mut field_elem_typ := init_sym.info.elem_type, field_sym.info.elem_type
mut init_elem_sym, mut field_elem_sym := c.table.sym(init_elem_typ), c.table.sym(field_elem_typ)
for {
if init_elem_sym.kind == .array_fixed
&& field_elem_sym.kind == .array_fixed {
init_elem_info = init_elem_sym.info as ast.ArrayFixed
init_elem_sym = c.table.sym(init_elem_info.elem_type)
field_elem_info = field_elem_sym.info as ast.ArrayFixed
field_elem_sym = c.table.sym(field_elem_info.elem_type)
if mut init_elem_sym.info is ast.ArrayFixed
&& mut field_elem_sym.info is ast.ArrayFixed {
init_elem_typ, field_elem_typ = init_elem_sym.info.elem_type, field_elem_sym.info.elem_type
init_elem_sym, field_elem_sym = c.table.sym(init_elem_typ), c.table.sym(field_elem_typ)
} else {
if field_elem_sym.name == gt_name {
mut elem_typ := init_elem_info.elem_type
if field_elem_info.elem_type.nr_muls() > 0
mut elem_typ := init_elem_typ
if field_elem_typ.nr_muls() > 0
&& elem_typ.nr_muls() > 0 {
elem_typ = elem_typ.set_nr_muls(0)
}
@@ -739,27 +732,25 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
}
}
}
} else if field_sym.kind == .map {
} else if field_sym.info is ast.Map {
for t in node.fields {
if ft.name == t.name {
init_sym := c.table.sym(t.typ)
if init_sym.kind == .map {
init_map_info := init_sym.info as ast.Map
field_map_info := field_sym.info as ast.Map
if field_map_info.key_type.has_flag(.generic)
&& c.table.sym(field_map_info.key_type).name == gt_name {
mut key_typ := init_map_info.key_type
if field_map_info.key_type.nr_muls() > 0
if init_sym.info is ast.Map {
if field_sym.info.key_type.has_flag(.generic)
&& c.table.sym(field_sym.info.key_type).name == gt_name {
mut key_typ := init_sym.info.key_type
if field_sym.info.key_type.nr_muls() > 0
&& key_typ.nr_muls() > 0 {
key_typ = key_typ.set_nr_muls(0)
}
concrete_types << key_typ
continue gname
}
if field_map_info.value_type.has_flag(.generic)
&& c.table.sym(field_map_info.value_type).name == gt_name {
mut val_typ := init_map_info.value_type
if field_map_info.value_type.nr_muls() > 0
if field_sym.info.value_type.has_flag(.generic)
&& c.table.sym(field_sym.info.value_type).name == gt_name {
mut val_typ := init_sym.info.value_type
if field_sym.info.value_type.nr_muls() > 0
&& val_typ.nr_muls() > 0 {
val_typ = val_typ.set_nr_muls(0)
}
@@ -769,18 +760,16 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
}
}
}
} else if field_sym.kind == .function {
} else if field_sym.info is ast.FnType {
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 init_sym.info is ast.FnType {
if field_sym.info.func.params.len == init_sym.info.func.params.len {
for n, fn_param in field_sym.info.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
mut arg_typ := init_sym.info.func.params[n].typ
if fn_param.typ.nr_muls() > 0 && arg_typ.nr_muls() > 0 {
arg_typ = arg_typ.set_nr_muls(0)
}
@@ -788,10 +777,10 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
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
if field_sym.info.func.return_type.has_flag(.generic)
&& c.table.sym(field_sym.info.func.return_type).name == gt_name {
mut ret_typ := init_sym.info.func.return_type
if field_sym.info.func.return_type.nr_muls() > 0
&& ret_typ.nr_muls() > 0 {
ret_typ = ret_typ.set_nr_muls(0)
}
@@ -861,9 +850,9 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
break
}
arg := node.args[arg_i]
param_type_sym := c.table.sym(param.typ)
param_sym := c.table.sym(param.typ)
if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
if param.typ.has_flag(.generic) && param_sym.name == gt_name {
typ = ast.mktyp(arg.typ)
sym := c.table.final_sym(arg.typ)
if sym.info is ast.FnType {
@@ -894,86 +883,76 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
arg_sym := c.table.final_sym(arg.typ)
if param.typ.has_flag(.variadic) {
typ = ast.mktyp(arg.typ)
} else if arg_sym.kind == .array && param_type_sym.kind == .array {
mut arg_elem_info := arg_sym.info as ast.Array
mut param_elem_info := param_type_sym.info as ast.Array
mut arg_elem_sym := c.table.sym(arg_elem_info.elem_type)
mut param_elem_sym := c.table.sym(param_elem_info.elem_type)
} else if arg_sym.info is ast.Array && param_sym.info is ast.Array {
mut arg_elem_typ, mut param_elem_typ := arg_sym.info.elem_type, param_sym.info.elem_type
mut arg_elem_sym, mut param_elem_sym := c.table.sym(arg_elem_typ), c.table.sym(param_elem_typ)
for {
if arg_elem_sym.kind == .array && param_elem_sym.kind == .array
if mut arg_elem_sym.info is ast.Array
&& mut param_elem_sym.info is ast.Array
&& c.table.cur_fn != unsafe { nil }
&& param_elem_sym.name !in c.table.cur_fn.generic_names {
arg_elem_info = arg_elem_sym.info as ast.Array
arg_elem_sym = c.table.sym(arg_elem_info.elem_type)
param_elem_info = param_elem_sym.info as ast.Array
param_elem_sym = c.table.sym(param_elem_info.elem_type)
arg_elem_typ, param_elem_typ = arg_elem_sym.info.elem_type, param_elem_sym.info.elem_type
arg_elem_sym, param_elem_sym = c.table.sym(arg_elem_typ), c.table.sym(param_elem_typ)
} else {
if param_elem_sym.name == gt_name {
typ = arg_elem_info.elem_type
if param_elem_info.elem_type.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = arg_elem_typ
if param_elem_typ.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = typ.set_nr_muls(0)
}
}
break
}
}
} else if arg_sym.kind == .array_fixed && param_type_sym.kind == .array_fixed {
mut arg_elem_info := arg_sym.info as ast.ArrayFixed
mut param_elem_info := param_type_sym.info as ast.ArrayFixed
mut arg_elem_sym := c.table.sym(arg_elem_info.elem_type)
mut param_elem_sym := c.table.sym(param_elem_info.elem_type)
} else if arg_sym.info is ast.ArrayFixed && param_sym.info is ast.ArrayFixed {
mut arg_elem_typ, mut param_elem_typ := arg_sym.info.elem_type, param_sym.info.elem_type
mut arg_elem_sym, mut param_elem_sym := c.table.sym(arg_elem_typ), c.table.sym(param_elem_typ)
for {
if arg_elem_sym.kind == .array_fixed && param_elem_sym.kind == .array_fixed
if mut arg_elem_sym.info is ast.ArrayFixed
&& mut param_elem_sym.info is ast.ArrayFixed
&& c.table.cur_fn != unsafe { nil }
&& param_elem_sym.name !in c.table.cur_fn.generic_names {
arg_elem_info = arg_elem_sym.info as ast.ArrayFixed
arg_elem_sym = c.table.sym(arg_elem_info.elem_type)
param_elem_info = param_elem_sym.info as ast.ArrayFixed
param_elem_sym = c.table.sym(param_elem_info.elem_type)
arg_elem_typ, param_elem_typ = arg_elem_sym.info.elem_type, param_elem_sym.info.elem_type
arg_elem_sym, param_elem_sym = c.table.sym(arg_elem_typ), c.table.sym(param_elem_typ)
} else {
if param_elem_sym.name == gt_name {
typ = arg_elem_info.elem_type
if param_elem_info.elem_type.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = arg_elem_typ
if param_elem_typ.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = typ.set_nr_muls(0)
}
}
break
}
}
} else if arg_sym.kind == .map && param_type_sym.kind == .map {
arg_map_info := arg_sym.info as ast.Map
param_map_info := param_type_sym.info as ast.Map
if param_map_info.key_type.has_flag(.generic)
&& c.table.sym(param_map_info.key_type).name == gt_name {
typ = arg_map_info.key_type
if param_map_info.key_type.nr_muls() > 0 && typ.nr_muls() > 0 {
} else if arg_sym.info is ast.Map && param_sym.info is ast.Map {
if param_sym.info.key_type.has_flag(.generic)
&& c.table.sym(param_sym.info.key_type).name == gt_name {
typ = arg_sym.info.key_type
if param_sym.info.key_type.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = typ.set_nr_muls(0)
}
}
if param_map_info.value_type.has_flag(.generic)
&& c.table.sym(param_map_info.value_type).name == gt_name {
typ = arg_map_info.value_type
if param_map_info.value_type.nr_muls() > 0 && typ.nr_muls() > 0 {
if param_sym.info.value_type.has_flag(.generic)
&& c.table.sym(param_sym.info.value_type).name == gt_name {
typ = arg_sym.info.value_type
if param_sym.info.value_type.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = typ.set_nr_muls(0)
}
}
} else if arg_sym.kind == .function && param_type_sym.kind == .function {
arg_type_func := (arg_sym.info as ast.FnType).func
param_type_func := (param_type_sym.info as ast.FnType).func
if param_type_func.params.len == arg_type_func.params.len {
for n, fn_param in param_type_func.params {
} else if arg_sym.info is ast.FnType && param_sym.info is ast.FnType {
if param_sym.info.func.params.len == arg_sym.info.func.params.len {
for n, fn_param in param_sym.info.func.params {
if fn_param.typ.has_flag(.generic)
&& c.table.sym(fn_param.typ).name == gt_name {
typ = arg_type_func.params[n].typ
typ = arg_sym.info.func.params[n].typ
if fn_param.typ.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = typ.set_nr_muls(0)
}
}
}
if param_type_func.return_type.has_flag(.generic)
&& c.table.sym(param_type_func.return_type).name == gt_name {
typ = arg_type_func.return_type
if param_type_func.return_type.nr_muls() > 0 && typ.nr_muls() > 0 {
if param_sym.info.func.return_type.has_flag(.generic)
&& c.table.sym(param_sym.info.func.return_type).name == gt_name {
typ = arg_sym.info.func.return_type
if param_sym.info.func.return_type.nr_muls() > 0 && typ.nr_muls() > 0 {
typ = typ.set_nr_muls(0)
}
}
@@ -983,8 +962,8 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
mut concrete_types := []ast.Type{}
match arg_sym.info {
ast.Struct, ast.Interface, ast.SumType {
if param_type_sym.generic_types.len > 0 {
generic_types = param_type_sym.generic_types.clone()
if param_sym.generic_types.len > 0 {
generic_types = param_sym.generic_types.clone()
} else {
generic_types = arg_sym.info.generic_types.clone()
}