From 010a591de352890a21d3fd212883ad1c6b7124e7 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 16 Oct 2025 09:19:36 -0300 Subject: [PATCH] cgen, type_resolver: Fix resolution type Map[string]T when T is AliasToMap (fix #25494) (#25510) --- vlib/v/ast/table.v | 5 +++++ vlib/v/gen/c/for.v | 15 ++++++++++++++ .../v/tests/generics/generic_map_alias_test.v | 20 +++++++++++++++++++ vlib/v/type_resolver/generic_resolver.v | 2 +- 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/generics/generic_map_alias_test.v diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index f72868bab..9c4b05cb9 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1876,6 +1876,11 @@ pub fn (mut t Table) convert_generic_type(generic_type Type, generic_names []str type_changed = true } if type_changed { + // map[Type]T where T is an alias to map type + if to_types.len == 1 && sym.info.value_type.has_flag(.generic) + && t.type_kind(to_types[0]) == .alias && t.final_sym(to_types[0]).kind == .map { + return unwrapped_value_type + } idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type) if unwrapped_key_type.has_flag(.generic) || unwrapped_value_type.has_flag(.generic) { return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) diff --git a/vlib/v/gen/c/for.v b/vlib/v/gen/c/for.v index a98690ffe..02d550927 100644 --- a/vlib/v/gen/c/for.v +++ b/vlib/v/gen/c/for.v @@ -201,6 +201,21 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { } node.val_type = g.table.value_type(unwrapped_typ) node.scope.update_var_type(node.val_var, node.val_type) + } else if node.kind == .alias { + mut unwrapped_typ := g.unwrap_generic(node.cond_type) + mut unwrapped_sym := g.table.final_sym(unwrapped_typ) + node.kind = unwrapped_sym.kind + node.cond_type = unwrapped_typ + if node.key_var.len > 0 { + key_type := match unwrapped_sym.kind { + .map { unwrapped_sym.map_info().key_type } + else { ast.int_type } + } + node.key_type = key_type + node.scope.update_var_type(node.key_var, key_type) + } + node.val_type = g.table.value_type(g.table.unaliased_type(unwrapped_typ)) + node.scope.update_var_type(node.val_var, node.val_type) } g.loop_depth++ if node.label.len > 0 { diff --git a/vlib/v/tests/generics/generic_map_alias_test.v b/vlib/v/tests/generics/generic_map_alias_test.v new file mode 100644 index 000000000..43698c241 --- /dev/null +++ b/vlib/v/tests/generics/generic_map_alias_test.v @@ -0,0 +1,20 @@ +import x.json2 + +pub struct AppJsonValue { +pub: + file string + md5 string + creat i64 +} + +pub type AppJson = map[string]AppJsonValue + +fn test_main() { + app_json1 := map[string]AppJsonValue{} + res1 := json2.encode(app_json1) + assert '${res1}' == '{}' + + app_json2 := AppJson{} + res2 := json2.encode(app_json2) + assert '${res2}' == '{}' +} diff --git a/vlib/v/type_resolver/generic_resolver.v b/vlib/v/type_resolver/generic_resolver.v index b6f5b3987..a032824f6 100644 --- a/vlib/v/type_resolver/generic_resolver.v +++ b/vlib/v/type_resolver/generic_resolver.v @@ -222,7 +222,7 @@ pub fn (mut t TypeResolver) resolve_args(cur_fn &ast.FnDecl, func &ast.Fn, mut n } } } else if arg_sym.kind == .any { - cparam_type_sym := t.table.sym(t.resolver.unwrap_generic(ctyp)) + cparam_type_sym := t.table.final_sym(t.resolver.unwrap_generic(ctyp)) if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array { comptime_args[k] = cparam_type_sym.info.elem_type } else if param_typ_sym.info is ast.Map -- 2.39.5