From 184a86343e4c3c7a0cb04ef7bf20a297242668e4 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 7 Oct 2024 20:12:28 +0800 Subject: [PATCH] all: cleanup resolve_generic_to_concrete() and related methods (#22433) --- vlib/v/ast/table.v | 106 ++++++++---------- vlib/v/ast/types.v | 6 +- vlib/v/checker/check_types.v | 2 +- vlib/v/checker/checker.v | 12 +- vlib/v/checker/fn.v | 20 ++-- vlib/v/checker/interface.v | 2 +- vlib/v/comptime/comptimeinfo.v | 4 +- vlib/v/gen/c/assign.v | 2 +- vlib/v/gen/c/fn.v | 26 ++--- vlib/v/gen/c/spawn_and_go.v | 16 +-- vlib/v/gen/c/struct.v | 6 +- vlib/v/gen/c/utils.v | 20 +--- vlib/v/gen/js/fn.v | 2 +- vlib/v/gen/js/js.v | 6 +- vlib/v/parser/parse_type.v | 22 ++-- vlib/v/parser/parser.v | 154 +++++++++++++------------- vlib/v/parser/struct.v | 4 +- vlib/v/tests/resolve_generic_2_test.v | 2 +- 18 files changed, 192 insertions(+), 220 deletions(-) diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 40da2e0dc..d845a26a3 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1570,7 +1570,7 @@ pub fn (t Table) does_type_implement_interface(typ Type, inter_typ Type) bool { return false } -pub fn (mut t Table) resolve_generic_static_type_name(fn_name string, generic_names []string, concrete_types []Type) string { +pub fn (mut t Table) convert_generic_static_type_name(fn_name string, generic_names []string, concrete_types []Type) string { if index := fn_name.index('__static__') { if index > 0 { generic_name := fn_name[0..index] @@ -1578,7 +1578,7 @@ pub fn (mut t Table) resolve_generic_static_type_name(fn_name string, generic_na && generic_name in generic_names if valid_generic { name_type := idx_to_type(t.find_type_idx(generic_name)).set_flag(.generic) - if typ := t.resolve_generic_to_concrete(name_type, generic_names, concrete_types) { + if typ := t.convert_generic_type(name_type, generic_names, concrete_types) { return '${t.type_to_str(typ)}${fn_name[index..]}' } } @@ -1587,20 +1587,18 @@ pub fn (mut t Table) resolve_generic_static_type_name(fn_name string, generic_na return fn_name } -// resolve_generic_to_concrete resolves generics to real types T => int. -// Even map[string]map[string]T can be resolved. -// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl. -pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_names []string, concrete_types []Type) ?Type { - if generic_names.len != concrete_types.len { +// convert_generic_type convert generics to real types (T => int) or other generics type. +pub fn (mut t Table) convert_generic_type(generic_type Type, generic_names []string, to_types []Type) ?Type { + if generic_names.len != to_types.len { return none } mut sym := t.sym(generic_type) if sym.name in generic_names { index := generic_names.index(sym.name) - if index >= concrete_types.len { + if index >= to_types.len { return none } - typ := concrete_types[index] + typ := to_types[index] if typ == 0 { return none } @@ -1613,7 +1611,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name match mut sym.info { Array { dims, elem_type := t.get_array_dims(sym.info) - if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) { + if typ := t.convert_generic_type(elem_type, generic_names, to_types) { idx := t.find_or_register_array_with_dims(typ, dims) if typ.has_flag(.generic) { return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) @@ -1623,9 +1621,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name } } ArrayFixed { - if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(sym.info.elem_type, generic_names, to_types) { idx := t.find_or_register_array_fixed(typ, sym.info.size, None{}, false) if typ.has_flag(.generic) { return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) @@ -1635,9 +1631,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name } } Chan { - if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(sym.info.elem_type, generic_names, to_types) { idx := t.find_or_register_chan(typ, typ.nr_muls() > 0) if typ.has_flag(.generic) { return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) @@ -1647,9 +1641,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name } } Thread { - if typ := t.resolve_generic_to_concrete(sym.info.return_type, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(sym.info.return_type, generic_names, to_types) { idx := t.find_or_register_thread(typ) if typ.has_flag(.generic) { return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) @@ -1662,9 +1654,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name mut func := sym.info.func mut has_generic := false if func.return_type.has_flag(.generic) { - if typ := t.resolve_generic_to_concrete(func.return_type, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(func.return_type, generic_names, to_types) { func.return_type = typ if typ.has_flag(.generic) { has_generic = true @@ -1674,9 +1664,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name func.params = func.params.clone() for mut param in func.params { if param.typ.has_flag(.generic) { - if typ := t.resolve_generic_to_concrete(param.typ, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(param.typ, generic_names, to_types) { param.typ = typ if typ.has_flag(.generic) { has_generic = true @@ -1697,7 +1685,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name mut types := []Type{} mut type_changed := false for ret_type in sym.info.types { - if typ := t.resolve_generic_to_concrete(ret_type, generic_names, concrete_types) { + if typ := t.convert_generic_type(ret_type, generic_names, to_types) { types << typ type_changed = true } else { @@ -1717,15 +1705,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name mut type_changed := false mut unwrapped_key_type := sym.info.key_type mut unwrapped_value_type := sym.info.value_type - if typ := t.resolve_generic_to_concrete(sym.info.key_type, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(sym.info.key_type, generic_names, to_types) { unwrapped_key_type = typ type_changed = true } - if typ := t.resolve_generic_to_concrete(sym.info.value_type, generic_names, - concrete_types) - { + if typ := t.convert_generic_type(sym.info.value_type, generic_names, to_types) { unwrapped_value_type = typ type_changed = true } @@ -1743,32 +1727,30 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name mut nrt := '${sym.name}[' mut rnrt := '${sym.rname}[' mut t_generic_names := generic_names.clone() - mut t_concrete_types := concrete_types.clone() + mut t_to_types := to_types.clone() if sym.generic_types.len > 0 && sym.generic_types.len == sym.info.generic_types.len && sym.generic_types != sym.info.generic_types { t_generic_names = sym.info.generic_types.map(t.sym(it).name) - t_concrete_types = [] + t_to_types = [] for t_typ in sym.generic_types { if !t_typ.has_flag(.generic) { - t_concrete_types << t_typ + t_to_types << t_typ } else if t.sym(t_typ).kind == .any { tname := t.sym(t_typ).name index := generic_names.index(tname) - if index >= 0 && index < concrete_types.len { - t_concrete_types << concrete_types[index] + if index >= 0 && index < to_types.len { + t_to_types << to_types[index] } } else { - if tt := t.resolve_generic_to_concrete(t_typ, generic_names, - concrete_types) - { - t_concrete_types << tt + if tt := t.convert_generic_type(t_typ, generic_names, to_types) { + t_to_types << tt } } } } for i in 0 .. sym.info.generic_types.len { - if ct := t.resolve_generic_to_concrete(sym.info.generic_types[i], - t_generic_names, t_concrete_types) + if ct := t.convert_generic_type(sym.info.generic_types[i], t_generic_names, + t_to_types) { gts := t.sym(ct) if ct.is_ptr() { @@ -1923,7 +1905,7 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr nrt = '${ts.name}[' c_nrt = '${ts.cname}_T_' for i in 0 .. ts.info.generic_types.len { - if ct := t.resolve_generic_to_concrete(ts.info.generic_types[i], t_generic_names, + if ct := t.convert_generic_type(ts.info.generic_types[i], t_generic_names, t_concrete_types) { gts := t.sym(ct) @@ -1955,7 +1937,7 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr fields[i].typ = t.unwrap_generic_type(fields[i].typ, t_generic_names, t_concrete_types) } else { - if t_typ := t.resolve_generic_to_concrete(fields[i].typ, t_generic_names, + if t_typ := t.convert_generic_type(fields[i].typ, t_generic_names, t_concrete_types) { fields[i].typ = t_typ @@ -1984,8 +1966,8 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr } // update concrete types for i in 0 .. ts.info.generic_types.len { - if t_typ := t.resolve_generic_to_concrete(ts.info.generic_types[i], - t_generic_names, t_concrete_types) + if t_typ := t.convert_generic_type(ts.info.generic_types[i], t_generic_names, + t_concrete_types) { final_concrete_types << t_typ } @@ -2044,7 +2026,7 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr variants[i] = t.unwrap_generic_type(variants[i], generic_names, concrete_types) } else { - if t_typ := t.resolve_generic_to_concrete(variants[i], generic_names, + if t_typ := t.convert_generic_type(variants[i], generic_names, concrete_types) { variants[i] = t_typ @@ -2075,13 +2057,13 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr // resolve generic types inside methods mut imethods := ts.info.methods.clone() for mut method in imethods { - if unwrap_typ := t.resolve_generic_to_concrete(method.return_type, generic_names, + if unwrap_typ := t.convert_generic_type(method.return_type, generic_names, concrete_types) { method.return_type = unwrap_typ } for mut param in method.params { - if unwrap_typ := t.resolve_generic_to_concrete(param.typ, generic_names, + if unwrap_typ := t.convert_generic_type(param.typ, generic_names, concrete_types) { param.typ = unwrap_typ @@ -2148,8 +2130,8 @@ pub fn (mut t Table) generic_insts_to_concrete() { fields[i].typ = t.unwrap_generic_type(fields[i].typ, generic_names, info.concrete_types) } - if t_typ := t.resolve_generic_to_concrete(fields[i].typ, - generic_names, info.concrete_types) + if t_typ := t.convert_generic_type(fields[i].typ, generic_names, + info.concrete_types) { fields[i].typ = t_typ } @@ -2196,7 +2178,7 @@ pub fn (mut t Table) generic_insts_to_concrete() { mut fields := parent_info.fields.clone() generic_names := t.get_generic_names(parent_info.generic_types) for i in 0 .. fields.len { - if t_typ := t.resolve_generic_to_concrete(fields[i].typ, generic_names, + if t_typ := t.convert_generic_type(fields[i].typ, generic_names, info.concrete_types) { fields[i].typ = t_typ @@ -2205,14 +2187,14 @@ pub fn (mut t Table) generic_insts_to_concrete() { mut imethods := parent_info.methods.clone() for mut method in imethods { method.generic_names.clear() - if pt := t.resolve_generic_to_concrete(method.return_type, - generic_names, info.concrete_types) + if pt := t.convert_generic_type(method.return_type, generic_names, + info.concrete_types) { method.return_type = pt } method.params = method.params.clone() for mut param in method.params { - if pt := t.resolve_generic_to_concrete(param.typ, generic_names, + if pt := t.convert_generic_type(param.typ, generic_names, info.concrete_types) { param.typ = pt @@ -2254,7 +2236,7 @@ pub fn (mut t Table) generic_insts_to_concrete() { mut variants := parent_info.variants.clone() generic_names := t.get_generic_names(parent_info.generic_types) for i in 0 .. fields.len { - if t_typ := t.resolve_generic_to_concrete(fields[i].typ, generic_names, + if t_typ := t.convert_generic_type(fields[i].typ, generic_names, info.concrete_types) { fields[i].typ = t_typ @@ -2267,8 +2249,8 @@ pub fn (mut t Table) generic_insts_to_concrete() { variants[i] = t.unwrap_generic_type(variants[i], generic_names, info.concrete_types) } else { - if t_typ := t.resolve_generic_to_concrete(variants[i], - generic_names, info.concrete_types) + if t_typ := t.convert_generic_type(variants[i], generic_names, + info.concrete_types) { variants[i] = t_typ } @@ -2295,7 +2277,7 @@ pub fn (mut t Table) generic_insts_to_concrete() { function.params = function.params.clone() for mut param in function.params { if param.typ.has_flag(.generic) { - if t_typ := t.resolve_generic_to_concrete(param.typ, function.generic_names, + if t_typ := t.convert_generic_type(param.typ, function.generic_names, info.concrete_types) { param.typ = t_typ @@ -2303,8 +2285,8 @@ pub fn (mut t Table) generic_insts_to_concrete() { } } if function.return_type.has_flag(.generic) { - if t_typ := t.resolve_generic_to_concrete(function.return_type, - function.generic_names, info.concrete_types) + if t_typ := t.convert_generic_type(function.return_type, function.generic_names, + info.concrete_types) { function.return_type = t_typ } diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 26908eb7a..a7381eec8 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -1708,7 +1708,7 @@ pub fn (t &TypeSymbol) find_method_with_generic_parent(name string) ?Fn { method.return_type = table.unwrap_generic_type(method.return_type, generic_names, t.info.concrete_types) } else { - if rt := table.resolve_generic_to_concrete(method.return_type, + if rt := table.convert_generic_type(method.return_type, generic_names, t.info.concrete_types) { method.return_type = rt @@ -1716,8 +1716,8 @@ pub fn (t &TypeSymbol) find_method_with_generic_parent(name string) ?Fn { } method.params = method.params.clone() for mut param in method.params { - if pt := table.resolve_generic_to_concrete(param.typ, - generic_names, t.info.concrete_types) + if pt := table.convert_generic_type(param.typ, generic_names, + t.info.concrete_types) { param.typ = pt } diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index b32628fe8..4a4bcb5de 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -1092,7 +1092,7 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) { } // resolve lambda with generic return type if arg.expr is ast.LambdaExpr && typ.has_flag(.generic) { - typ = c.comptime.resolve_generic_expr(arg.expr.expr, typ) + typ = c.comptime.unwrap_generic_expr(arg.expr.expr, typ) if typ.has_flag(.generic) { lambda_ret_gt_name := c.table.type_to_str(typ) idx := func.generic_names.index(lambda_ret_gt_name) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fb99b0d7c..82b1abde0 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1051,7 +1051,7 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to } mut inferred_type := interface_type if generic_info.is_generic { - inferred_type = c.resolve_generic_interface(typ, generic_type, pos) + inferred_type = c.unwrap_generic_interface(typ, generic_type, pos) if inferred_type == 0 { return false } @@ -2739,18 +2739,18 @@ fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { if c.inside_generic_struct_init { generic_names := c.cur_struct_generic_types.map(c.table.sym(it).name) - if t_typ := c.table.resolve_generic_to_concrete(typ, generic_names, c.cur_struct_concrete_types) { + if t_typ := c.table.convert_generic_type(typ, generic_names, c.cur_struct_concrete_types) { return t_typ } } if c.table.cur_fn != unsafe { nil } { - if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names, + if t_typ := c.table.convert_generic_type(typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types) { return t_typ } if c.inside_lambda && c.table.cur_lambda.call_ctx != unsafe { nil } { - if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_lambda.func.decl.generic_names, + if t_typ := c.table.convert_generic_type(typ, c.table.cur_lambda.func.decl.generic_names, c.table.cur_lambda.call_ctx.concrete_types) { return t_typ @@ -3326,7 +3326,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { c.mark_as_referenced(mut &node.expr, true) } if to_sym.info.is_generic { - inferred_type := c.resolve_generic_interface(from_type, to_type, node.pos) + inferred_type := c.unwrap_generic_interface(from_type, to_type, node.pos) if inferred_type != 0 { to_type = inferred_type to_sym = c.table.sym(to_type) @@ -3717,7 +3717,7 @@ fn (mut c Checker) resolve_var_fn(func ast.Fn, mut node ast.Ident, name string) mut fn_type := ast.new_type(c.table.find_or_register_fn_type(func, false, true)) if func.generic_names.len > 0 { concrete_types := node.concrete_types.map(c.unwrap_generic(it)) - if typ_ := c.table.resolve_generic_to_concrete(fn_type, func.generic_names, concrete_types) { + if typ_ := c.table.convert_generic_type(fn_type, func.generic_names, concrete_types) { fn_type = typ_ if concrete_types.all(!it.has_flag(.generic)) { c.table.register_fn_concrete_types(func.fkey(), concrete_types) diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 451dc8a47..6981f375e 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -770,7 +770,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. if index := node.name.index('__static__') { // resolve static call T.name() if index > 0 && c.table.cur_fn != unsafe { nil } { - fn_name = c.table.resolve_generic_static_type_name(fn_name, c.table.cur_fn.generic_names, + fn_name = c.table.convert_generic_static_type_name(fn_name, c.table.cur_fn.generic_names, c.table.cur_concrete_types) } } @@ -1592,7 +1592,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. }) if param.typ.has_flag(.generic) && func.generic_names.len == node.concrete_types.len { - if unwrap_typ := c.table.resolve_generic_to_concrete(param.typ, func.generic_names, + if unwrap_typ := c.table.convert_generic_type(param.typ, func.generic_names, concrete_types) { utyp := c.unwrap_generic(typ) @@ -1643,9 +1643,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. } if node.concrete_types.len > 0 && func.return_type != 0 && c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len == 0 { - if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names, - concrete_types) - { + if typ := c.table.convert_generic_type(func.return_type, func.generic_names, concrete_types) { node.return_type = typ c.register_trace_call(node, func) return typ @@ -1657,7 +1655,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. if func.generic_names.len > 0 { if has_generic || node.concrete_types.any(it.has_flag(.generic)) { - if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names, + if typ := c.table.convert_generic_type(func.return_type, func.generic_names, node.concrete_types) { if typ.has_flag(.generic) { @@ -1668,7 +1666,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. return node.return_type } else { if node.concrete_types.len > 0 && !node.concrete_types.any(it.has_flag(.generic)) { - if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names, + if typ := c.table.convert_generic_type(func.return_type, func.generic_names, node.concrete_types) { node.return_type = typ @@ -1676,7 +1674,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. return typ } } - if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names, + if typ := c.table.convert_generic_type(func.return_type, func.generic_names, concrete_types) { if typ.has_flag(.generic) { @@ -2507,7 +2505,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } else { concrete_types } - if exp_utyp := c.table.resolve_generic_to_concrete(exp_arg_typ, method.generic_names, + if exp_utyp := c.table.convert_generic_type(exp_arg_typ, method.generic_names, method_concrete_types) { exp_arg_typ = exp_utyp @@ -2518,7 +2516,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { if c.table.cur_fn != unsafe { nil } && c.table.cur_concrete_types.len > 0 { got_arg_typ = c.unwrap_generic(got_arg_typ) } else { - if got_utyp := c.table.resolve_generic_to_concrete(got_arg_typ, method.generic_names, + if got_utyp := c.table.convert_generic_type(got_arg_typ, method.generic_names, method_concrete_types) { got_arg_typ = got_utyp @@ -2636,7 +2634,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { if node.concrete_types.len > 0 && node.concrete_types.all(!it.has_flag(.generic)) && method.return_type.has_flag(.generic) && method.generic_names.len > 0 && method.generic_names.len == node.concrete_types.len { - if typ := c.table.resolve_generic_to_concrete(method.return_type, method.generic_names, + if typ := c.table.convert_generic_type(method.return_type, method.generic_names, concrete_types) { node.return_type = typ diff --git a/vlib/v/checker/interface.v b/vlib/v/checker/interface.v index c4d6b849b..a8e3e3f6e 100644 --- a/vlib/v/checker/interface.v +++ b/vlib/v/checker/interface.v @@ -233,7 +233,7 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) { } } -fn (mut c Checker) resolve_generic_interface(typ ast.Type, interface_type ast.Type, pos token.Pos) ast.Type { +fn (mut c Checker) unwrap_generic_interface(typ ast.Type, interface_type ast.Type, pos token.Pos) ast.Type { utyp := c.unwrap_generic(typ) typ_sym := c.table.sym(utyp) mut inter_sym := c.table.sym(interface_type) diff --git a/vlib/v/comptime/comptimeinfo.v b/vlib/v/comptime/comptimeinfo.v index 3d340a827..74fcb8d70 100644 --- a/vlib/v/comptime/comptimeinfo.v +++ b/vlib/v/comptime/comptimeinfo.v @@ -285,10 +285,10 @@ fn (mut ct ComptimeInfo) comptime_get_kind_var(var ast.Ident) ?ast.ComptimeForKi } } -pub fn (mut ct ComptimeInfo) resolve_generic_expr(expr ast.Expr, default_typ ast.Type) ast.Type { +pub fn (mut ct ComptimeInfo) unwrap_generic_expr(expr ast.Expr, default_typ ast.Type) ast.Type { match expr { ast.ParExpr { - return ct.resolve_generic_expr(expr.expr, default_typ) + return ct.unwrap_generic_expr(expr.expr, default_typ) } ast.CastExpr { return expr.typ diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 1e12916f3..4667040cb 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -1170,7 +1170,7 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) { } ast.CallExpr { if val.is_method { - unwrapped_rec_type, typ_sym := g.resolve_receiver_type(val) + unwrapped_rec_type, typ_sym := g.unwrap_receiver_type(val) left_type := g.unwrap_generic(val.left_type) left_sym := g.table.sym(left_type) final_left_sym := g.table.final_sym(left_type) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 05fc32b3a..52ae5fae2 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1251,7 +1251,7 @@ fn (mut g Gen) resolve_fn_return_type(node ast.CallExpr) ast.Type { } } } - if gen_type := g.table.resolve_generic_to_concrete(node.return_type_generic, + if gen_type := g.table.convert_generic_type(node.return_type_generic, func.generic_names, concrete_types) { if !gen_type.has_flag(.generic) { @@ -1279,7 +1279,7 @@ fn (mut g Gen) resolve_fn_return_type(node ast.CallExpr) ast.Type { } } } - if gen_type := g.table.resolve_generic_to_concrete(node.return_type_generic, + if gen_type := g.table.convert_generic_type(node.return_type_generic, func.generic_names, concrete_types) { if !gen_type.has_flag(.generic) { @@ -1513,12 +1513,12 @@ fn (mut g Gen) resolve_receiver_name(node ast.CallExpr, unwrapped_rec_type ast.T return receiver_type_name } -fn (mut g Gen) resolve_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymbol) { +fn (mut g Gen) unwrap_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymbol) { left_type := g.unwrap_generic(node.left_type) mut unwrapped_rec_type := node.receiver_type if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 { // in generic fn unwrapped_rec_type = g.unwrap_generic(node.receiver_type) - unwrapped_rec_type = g.comptime.resolve_generic_expr(node.left, unwrapped_rec_type) + unwrapped_rec_type = g.comptime.unwrap_generic_expr(node.left, unwrapped_rec_type) } else { // in non-generic fn sym := g.table.sym(node.receiver_type) match sym.info { @@ -1526,7 +1526,7 @@ fn (mut g Gen) resolve_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymb generic_names := sym.info.generic_types.map(g.table.sym(it).name) // see comment at top of vlib/v/gen/c/utils.v mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(node.receiver_type, generic_names, + if utyp := muttable.convert_generic_type(node.receiver_type, generic_names, sym.info.concrete_types) { unwrapped_rec_type = utyp @@ -1580,7 +1580,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { g.checker_bug('CallExpr.receiver_type is 0 in method_call', node.pos) } left_type := g.unwrap_generic(node.left_type) - mut unwrapped_rec_type, typ_sym := g.resolve_receiver_type(node) + mut unwrapped_rec_type, typ_sym := g.unwrap_receiver_type(node) rec_cc_type := g.cc_type(unwrapped_rec_type, false) mut receiver_type_name := util.no_dots(rec_cc_type) @@ -1931,7 +1931,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { if index := node.name.index('__static__') { // resolve static call T.name() if index > 0 && g.cur_fn != unsafe { nil } { - name = g.table.resolve_generic_static_type_name(node.name, g.cur_fn.generic_names, + name = g.table.convert_generic_static_type_name(node.name, g.cur_fn.generic_names, g.cur_concrete_types) } } @@ -2417,7 +2417,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) { if func.generic_names.len > 0 { for i in 0 .. expected_types.len { mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(node.expected_arg_types[i], + if utyp := muttable.convert_generic_type(node.expected_arg_types[i], func.generic_names, node.concrete_types) { expected_types[i] = utyp @@ -2430,7 +2430,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) { if func.generic_names.len > 0 { for i in 0 .. expected_types.len { mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(node.expected_arg_types[i], + if utyp := muttable.convert_generic_type(node.expected_arg_types[i], func.generic_names, node.concrete_types) { expected_types[i] = utyp @@ -2556,8 +2556,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { left_sym := g.table.sym(node.left_type) if fn_def := left_sym.find_method_with_generic_parent(node.name) { mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, - fn_def.generic_names, node.concrete_types) + if utyp := muttable.convert_generic_type(arr_info.elem_type, fn_def.generic_names, + node.concrete_types) { arr_info.elem_type = utyp } @@ -2567,8 +2567,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } else { if fn_def := g.table.find_fn(node.name) { mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(arr_info.elem_type, - fn_def.generic_names, node.concrete_types) + if utyp := muttable.convert_generic_type(arr_info.elem_type, fn_def.generic_names, + node.concrete_types) { arr_info.elem_type = utyp } diff --git a/vlib/v/gen/c/spawn_and_go.v b/vlib/v/gen/c/spawn_and_go.v index fecc1eada..12952fb77 100644 --- a/vlib/v/gen/c/spawn_and_go.v +++ b/vlib/v/gen/c/spawn_and_go.v @@ -239,21 +239,21 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { rec_sym := g.table.sym(g.unwrap_generic(node.call_expr.receiver_type)) if f := rec_sym.find_method_with_generic_parent(node.call_expr.name) { mut muttable := unsafe { &ast.Table(g.table) } - return_type := muttable.resolve_generic_to_concrete(f.return_type, - f.generic_names, node.call_expr.concrete_types) or { f.return_type } + return_type := muttable.convert_generic_type(f.return_type, f.generic_names, + node.call_expr.concrete_types) or { f.return_type } mut arg_types := f.params.map(it.typ) - arg_types = arg_types.map(muttable.resolve_generic_to_concrete(it, - f.generic_names, node.call_expr.concrete_types) or { it }) + arg_types = arg_types.map(muttable.convert_generic_type(it, f.generic_names, + node.call_expr.concrete_types) or { it }) fn_var = g.fn_var_signature(return_type, arg_types, 'fn') } } else { if f := g.table.find_fn(node.call_expr.name) { mut muttable := unsafe { &ast.Table(g.table) } - return_type := muttable.resolve_generic_to_concrete(f.return_type, - f.generic_names, node.call_expr.concrete_types) or { f.return_type } + return_type := muttable.convert_generic_type(f.return_type, f.generic_names, + node.call_expr.concrete_types) or { f.return_type } mut arg_types := f.params.map(it.typ) - arg_types = arg_types.map(muttable.resolve_generic_to_concrete(it, - f.generic_names, node.call_expr.concrete_types) or { it }) + arg_types = arg_types.map(muttable.convert_generic_type(it, f.generic_names, + node.call_expr.concrete_types) or { it }) for i, typ in arg_types { mut typ_sym := g.table.sym(typ) for { diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index 7a8cecbc3..0cf003e9d 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -253,7 +253,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) { t_concrete_types << g.cur_concrete_types[index] } } else { - if tt := g.table.resolve_generic_to_concrete(t_typ, g.table.cur_fn.generic_names, + if tt := g.table.convert_generic_type(t_typ, g.table.cur_fn.generic_names, g.cur_concrete_types) { t_concrete_types << tt @@ -261,8 +261,8 @@ fn (mut g Gen) struct_init(node ast.StructInit) { } } } - if tt := g.table.resolve_generic_to_concrete(sfield.expected_type, - t_generic_names, t_concrete_types) + if tt := g.table.convert_generic_type(sfield.expected_type, t_generic_names, + t_concrete_types) { sfield.expected_type = tt } diff --git a/vlib/v/gen/c/utils.v b/vlib/v/gen/c/utils.v index 3f7be272c..b30bcae60 100644 --- a/vlib/v/gen/c/utils.v +++ b/vlib/v/gen/c/utils.v @@ -7,18 +7,16 @@ import v.ast fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { - // NOTE: `resolve_generic_to_concrete` should not mutate the table. + // NOTE: `convert_generic_type` should not mutate the table. // // It mutates if the generic type is for example `[]T` and the concrete // type is an array type that has not been registered yet. // // This should have already happened in the checker, since it also calls - // `resolve_generic_to_concrete`. `g.table` is made non-mut to make sure + // `convert_generic_type`. `g.table` is made non-mut to make sure // no one else can accidentally mutates the table. if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 { - if t_typ := g.table.resolve_generic_to_concrete(typ, g.cur_fn.generic_names, - g.cur_concrete_types) - { + if t_typ := g.table.convert_generic_type(typ, g.cur_fn.generic_names, g.cur_concrete_types) { return t_typ } } else if g.inside_struct_init { @@ -27,9 +25,7 @@ fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type { if sym.info is ast.Struct { if sym.info.generic_types.len > 0 { generic_names := sym.info.generic_types.map(g.table.sym(it).name) - if t_typ := g.table.resolve_generic_to_concrete(typ, generic_names, - sym.info.concrete_types) - { + if t_typ := g.table.convert_generic_type(typ, generic_names, sym.info.concrete_types) { return t_typ } } @@ -41,15 +37,11 @@ fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type { if sym.info is ast.Struct { if sym.info.generic_types.len > 0 { generic_names := sym.info.generic_types.map(g.table.sym(it).name) - if t_typ := g.table.resolve_generic_to_concrete(typ, generic_names, - sym.info.concrete_types) - { + if t_typ := g.table.convert_generic_type(typ, generic_names, sym.info.concrete_types) { return t_typ } - if t_typ := g.table.resolve_generic_to_concrete(typ, generic_names, - g.cur_concrete_types) - { + if t_typ := g.table.convert_generic_type(typ, generic_names, g.cur_concrete_types) { return t_typ } } diff --git a/vlib/v/gen/js/fn.v b/vlib/v/gen/js/fn.v index 838d234b9..d9e182ea7 100644 --- a/vlib/v/gen/js/fn.v +++ b/vlib/v/gen/js/fn.v @@ -231,7 +231,7 @@ fn (mut g JsGen) method_call(node ast.CallExpr) { generic_names := sym.info.generic_types.map(g.table.sym(it).name) // see comment at top of vlib/v/gen/c/utils.v mut muttable := unsafe { &ast.Table(g.table) } - if utyp := muttable.resolve_generic_to_concrete(node.receiver_type, generic_names, + if utyp := muttable.convert_generic_type(node.receiver_type, generic_names, sym.info.concrete_types) { unwrapped_rec_type = utyp diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 8ebeccaf1..5e1b1dd70 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -3631,15 +3631,15 @@ fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) { fn (mut g JsGen) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { /* - resolve_generic_to_concrete should not mutate the table. + convert_generic_type should not mutate the table. It mutates if the generic type is for example []T and the concrete type is an array type that has not been registered yet. This should have already happened in the checker, since - it also calls resolve_generic_to_concrete. g.table is made + it also calls convert_generic_type. g.table is made non-mut to make sure no one else can accidentally mutates the table. */ mut muttable := unsafe { &ast.Table(g.table) } - if t_typ := muttable.resolve_generic_to_concrete(typ, if unsafe { g.fn_decl != 0 } { + if t_typ := muttable.convert_generic_type(typ, if unsafe { g.fn_decl != 0 } { g.fn_decl.generic_names } else { []string{} diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 0c748eb23..a22bb1393 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -803,9 +803,9 @@ fn (mut p Parser) find_type_or_add_placeholder(name string, language ast.Languag sym := p.table.sym(typ) match sym.info { ast.Struct, ast.Interface, ast.SumType { - if p.struct_init_generic_types.len > 0 && sym.info.generic_types.len > 0 - && p.struct_init_generic_types != sym.info.generic_types { - generic_names := p.types_to_names(p.struct_init_generic_types, p.tok.pos(), + if p.init_generic_types.len > 0 && sym.info.generic_types.len > 0 + && p.init_generic_types != sym.info.generic_types { + generic_names := p.types_to_names(p.init_generic_types, p.tok.pos(), 'struct_init_generic_types') or { return ast.no_type } // NOTE: // Used here for the wraparound `< >` characters, is not a reserved character in generic syntax, @@ -835,15 +835,15 @@ fn (mut p Parser) find_type_or_add_placeholder(name string, language ast.Languag ...sym name: sym_name rname: sym.name - generic_types: p.struct_init_generic_types.clone() + generic_types: p.init_generic_types.clone() }) } typ = ast.new_type(idx) } } ast.FnType { - if p.struct_init_generic_types.len > 0 && sym.info.func.generic_names.len > 0 { - generic_names := p.types_to_names(p.struct_init_generic_types, p.tok.pos(), + if p.init_generic_types.len > 0 && sym.info.func.generic_names.len > 0 { + generic_names := p.types_to_names(p.init_generic_types, p.tok.pos(), 'struct_init_generic_types') or { return ast.no_type } if generic_names != sym.info.func.generic_names { mut sym_name := sym.name + '<' @@ -862,16 +862,16 @@ fn (mut p Parser) find_type_or_add_placeholder(name string, language ast.Languag func.name = sym_name func.generic_names = generic_names.clone() if func.return_type.has_flag(.generic) { - if to_generic_typ := p.table.resolve_generic_to_concrete(func.return_type, - sym.info.func.generic_names, p.struct_init_generic_types) + if to_generic_typ := p.table.convert_generic_type(func.return_type, + sym.info.func.generic_names, p.init_generic_types) { func.return_type = to_generic_typ } } for i in 0 .. func.params.len { if func.params[i].typ.has_flag(.generic) { - if to_generic_typ := p.table.resolve_generic_to_concrete(func.params[i].typ, - sym.info.func.generic_names, p.struct_init_generic_types) + if to_generic_typ := p.table.convert_generic_type(func.params[i].typ, + sym.info.func.generic_names, p.init_generic_types) { func.params[i].typ = to_generic_typ } @@ -953,7 +953,7 @@ fn (mut p Parser) parse_generic_inst_type(name string) ast.Type { bs_cname += '_' } if !is_instance { - p.struct_init_generic_types = concrete_types + p.init_generic_types = concrete_types } concrete_types_pos := start_pos.extend(p.tok.pos()) p.next() diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index d0e2287c8..3e4a146f5 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -29,83 +29,83 @@ mut: unique_prefix string // a hash of p.file_path, used for making anon fn generation unique file_backend_mode ast.Language // .c for .c.v|.c.vv|.c.vsh files; .js for .js.v files, .amd64/.rv32/other arches for .amd64.v/.rv32.v/etc. files, .v otherwise. // see comment in parse_file - tok token.Token - prev_tok token.Token - peek_tok token.Token - language ast.Language - fn_language ast.Language // .c for `fn C.abcd()` declarations - expr_level int // prevent too deep recursions for pathological programs - inside_vlib_file bool // true for all vlib/ files - inside_test_file bool // when inside _test.v or _test.vv file - inside_if bool - inside_comptime_if bool - inside_if_expr bool - inside_if_cond bool - inside_ct_if_expr bool - inside_or_expr bool - inside_for bool - inside_for_expr bool - inside_fn bool // true even with implicit main - inside_fn_return bool - inside_fn_concrete_type bool // parsing fn_name[concrete_type]() call expr - inside_call_args bool // true inside f( .... ) - inside_unsafe_fn bool - inside_str_interp bool - inside_array_lit bool - inside_in_array bool - inside_infix bool - inside_match bool // to separate `match A { }` from `Struct{}` - inside_select bool // to allow `ch <- Struct{} {` inside `select` - inside_match_case bool // to separate `match_expr { }` from `Struct{}` - inside_match_body bool // to fix eval not used TODO - inside_unsafe bool - inside_sum_type bool // to prevent parsing inline sum type again - inside_asm_template bool - inside_asm bool - inside_defer bool - inside_generic_params bool // indicates if parsing between `<` and `>` of a method/function - inside_receiver_param bool // indicates if parsing the receiver parameter inside the first `(` and `)` of a method - inside_struct_field_decl bool - inside_struct_attr_decl bool - inside_map_init bool - inside_orm bool - inside_chan_decl bool - inside_attr_decl bool - fixed_array_dim int // fixed array dim parsing level - or_is_handled bool // ignore `or` in this expression - builtin_mod bool // are we in the `builtin` module? - mod string // current module name - is_manualfree bool // true when `@[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree - has_globals bool // `@[has_globals] module abc` - allow globals declarations, even without -enable-globals, in that single .v file __only__ - is_generated bool // `@[generated] module abc` - turn off compiler notices for that single .v file __only__. - is_translated bool // `@[translated] module abc` - mark a file as translated, to relax some compiler checks for translated code. - attrs []ast.Attr // attributes before next decl stmt - expr_mod string // for constructing full type names in parse_type() - imports map[string]string // alias => mod_name - ast_imports []ast.Import // mod_names - used_imports []string // alias - auto_imports []string // imports, the user does not need to specify - imported_symbols map[string]string - is_amp bool // for generating the right code for `&Foo{}` - returns bool - is_stmt_ident bool // true while the beginning of a statement is an ident/selector - expecting_type bool // `is Type`, expecting type - cur_fn_name string - label_names []string - name_error bool // indicates if the token is not a name or the name is on another line - n_asm int // controls assembly labels - global_labels []string - comptime_if_cond bool - defer_vars []ast.Ident - should_abort bool // when too many errors/warnings/notices are accumulated, should_abort becomes true, and the parser should stop - codegen_text string - anon_struct_decl ast.StructDecl - struct_init_generic_types []ast.Type - if_cond_comments []ast.Comment - left_comments []ast.Comment - script_mode bool - script_mode_start_token token.Token - generic_type_level int // to avoid infinite recursion segfaults due to compiler bugs in ensure_type_exists + tok token.Token + prev_tok token.Token + peek_tok token.Token + language ast.Language + fn_language ast.Language // .c for `fn C.abcd()` declarations + expr_level int // prevent too deep recursions for pathological programs + inside_vlib_file bool // true for all vlib/ files + inside_test_file bool // when inside _test.v or _test.vv file + inside_if bool + inside_comptime_if bool + inside_if_expr bool + inside_if_cond bool + inside_ct_if_expr bool + inside_or_expr bool + inside_for bool + inside_for_expr bool + inside_fn bool // true even with implicit main + inside_fn_return bool + inside_fn_concrete_type bool // parsing fn_name[concrete_type]() call expr + inside_call_args bool // true inside f( .... ) + inside_unsafe_fn bool + inside_str_interp bool + inside_array_lit bool + inside_in_array bool + inside_infix bool + inside_match bool // to separate `match A { }` from `Struct{}` + inside_select bool // to allow `ch <- Struct{} {` inside `select` + inside_match_case bool // to separate `match_expr { }` from `Struct{}` + inside_match_body bool // to fix eval not used TODO + inside_unsafe bool + inside_sum_type bool // to prevent parsing inline sum type again + inside_asm_template bool + inside_asm bool + inside_defer bool + inside_generic_params bool // indicates if parsing between `<` and `>` of a method/function + inside_receiver_param bool // indicates if parsing the receiver parameter inside the first `(` and `)` of a method + inside_struct_field_decl bool + inside_struct_attr_decl bool + inside_map_init bool + inside_orm bool + inside_chan_decl bool + inside_attr_decl bool + fixed_array_dim int // fixed array dim parsing level + or_is_handled bool // ignore `or` in this expression + builtin_mod bool // are we in the `builtin` module? + mod string // current module name + is_manualfree bool // true when `@[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree + has_globals bool // `@[has_globals] module abc` - allow globals declarations, even without -enable-globals, in that single .v file __only__ + is_generated bool // `@[generated] module abc` - turn off compiler notices for that single .v file __only__. + is_translated bool // `@[translated] module abc` - mark a file as translated, to relax some compiler checks for translated code. + attrs []ast.Attr // attributes before next decl stmt + expr_mod string // for constructing full type names in parse_type() + imports map[string]string // alias => mod_name + ast_imports []ast.Import // mod_names + used_imports []string // alias + auto_imports []string // imports, the user does not need to specify + imported_symbols map[string]string + is_amp bool // for generating the right code for `&Foo{}` + returns bool + is_stmt_ident bool // true while the beginning of a statement is an ident/selector + expecting_type bool // `is Type`, expecting type + cur_fn_name string + label_names []string + name_error bool // indicates if the token is not a name or the name is on another line + n_asm int // controls assembly labels + global_labels []string + comptime_if_cond bool + defer_vars []ast.Ident + should_abort bool // when too many errors/warnings/notices are accumulated, should_abort becomes true, and the parser should stop + codegen_text string + anon_struct_decl ast.StructDecl + init_generic_types []ast.Type + if_cond_comments []ast.Comment + left_comments []ast.Comment + script_mode bool + script_mode_start_token token.Token + generic_type_level int // to avoid infinite recursion segfaults due to compiler bugs in ensure_type_exists pub mut: scanner &scanner.Scanner = unsafe { nil } table &ast.Table = unsafe { nil } diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index d0a518ad3..7e0050929 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -412,9 +412,9 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option bool) ast.StructInit { first_pos := (if kind == .short_syntax && p.prev_tok.kind == .lcbr { p.prev_tok } else { p.tok }).pos() - p.struct_init_generic_types = []ast.Type{} + p.init_generic_types = []ast.Type{} mut typ := if kind == .short_syntax { ast.void_type } else { p.parse_type() } - struct_init_generic_types := p.struct_init_generic_types.clone() + struct_init_generic_types := p.init_generic_types.clone() if is_option { typ = typ.set_flag(.option) } diff --git a/vlib/v/tests/resolve_generic_2_test.v b/vlib/v/tests/resolve_generic_2_test.v index d3b9c7b9c..360f1e1e5 100644 --- a/vlib/v/tests/resolve_generic_2_test.v +++ b/vlib/v/tests/resolve_generic_2_test.v @@ -1,4 +1,4 @@ -fn test_resolve_generic_params() { +fn test_unwrap_generic_params() { assert encode(true) == [] assert encode([true]) == ['[]bool'] assert encode(1) == [] -- 2.39.5