diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index bcddea101f18ef..9d7b5644ac9df2 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1729,22 +1729,21 @@ fn (mut c Checker) resolve_comptime_args(func ast.Fn, node_ ast.CallExpr, concre mut ctyp := c.comptime.get_comptime_var_type(call_arg.expr) if ctyp != ast.void_type { arg_sym := c.table.sym(ctyp) + param_sym := c.table.final_sym(param_typ) if arg_sym.info is ast.Array && param_typ.has_flag(.generic) - && c.table.final_sym(param_typ).kind == .array { + && param_sym.kind == .array { ctyp = arg_sym.info.elem_type } else if arg_sym.info is ast.Map && param_typ.has_flag(.generic) - && c.table.final_sym(param_typ).kind == .map { - map_info := c.table.final_sym(param_typ).info as ast.Map - key_is_generic := map_info.key_type.has_flag(.generic) - if key_is_generic { + && param_sym.info is ast.Map { + if param_sym.info.key_type.has_flag(.generic) { ctyp = c.unwrap_generic(arg_sym.info.key_type) - } - if map_info.value_type.has_flag(.generic) { - if key_is_generic { + if param_sym.info.value_type.has_flag(.generic) { comptime_args[k] = ctyp k++ + ctyp = c.unwrap_generic(arg_sym.info.key_type) } - ctyp = c.unwrap_generic(arg_sym.info.key_type) + } else if param_sym.info.value_type.has_flag(.generic) { + ctyp = c.unwrap_generic(arg_sym.info.value_type) } } comptime_args[k] = ctyp @@ -1754,7 +1753,6 @@ fn (mut c Checker) resolve_comptime_args(func ast.Fn, node_ ast.CallExpr, concre if ctyp != ast.void_type { arg_sym := c.table.final_sym(call_arg.typ) param_typ_sym := c.table.sym(param_typ) - if param_typ.has_flag(.variadic) { ctyp = ast.mktyp(ctyp) comptime_args[k] = ctyp @@ -1787,11 +1785,19 @@ fn (mut c Checker) resolve_comptime_args(func ast.Fn, node_ ast.CallExpr, concre cparam_type_sym := c.table.sym(c.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.kind == .map + } else if param_typ_sym.info is ast.Map && cparam_type_sym.info is ast.Map { - comptime_args[k] = cparam_type_sym.info.key_type - comptime_args[k + 1] = cparam_type_sym.info.value_type - k++ + key_is_generic := param_typ_sym.info.key_type.has_flag(.generic) + if key_is_generic { + comptime_args[k] = cparam_type_sym.info.key_type + } + if param_typ_sym.info.value_type.has_flag(.generic) { + k2 := if key_is_generic { k + 1 } else { k } + comptime_args[k2] = cparam_type_sym.info.value_type + if key_is_generic { + k++ + } + } } else { if node_.args[i].expr.is_auto_deref_var() { ctyp = ctyp.deref() diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index e6ee6d88857cb2..a419fa3de98508 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1362,11 +1362,17 @@ fn (mut g Gen) resolve_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concre cparam_type_sym := g.table.sym(g.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.kind == .map + } else if param_typ_sym.info is ast.Map && cparam_type_sym.info is ast.Map { - comptime_args[k] = cparam_type_sym.info.key_type - comptime_args[k + 1] = cparam_type_sym.info.value_type - k++ + if param_typ_sym.info.key_type.has_flag(.generic) { + comptime_args[k] = cparam_type_sym.info.key_type + if param_typ_sym.info.value_type.has_flag(.generic) { + k++ + comptime_args[k] = cparam_type_sym.info.value_type + } + } else if param_typ_sym.info.value_type.has_flag(.generic) { + comptime_args[k] = cparam_type_sym.info.value_type + } } else { if node_.args[i].expr.is_auto_deref_var() { ctyp = ctyp.deref() @@ -1411,14 +1417,13 @@ fn (mut g Gen) resolve_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concre && param_typ.has_flag(.generic) { comptime_sym := g.table.sym(comptime_args[k]) if comptime_sym.info is ast.Map { - key_is_generic := param_sym.info.key_type.has_flag(.generic) - if key_is_generic { + if param_sym.info.key_type.has_flag(.generic) { comptime_args[k] = comptime_sym.info.key_type - } - if param_sym.info.value_type.has_flag(.generic) { - if key_is_generic { + if param_sym.info.value_type.has_flag(.generic) { k++ + comptime_args[k] = comptime_sym.info.value_type } + } else if param_sym.info.value_type.has_flag(.generic) { comptime_args[k] = comptime_sym.info.value_type } } diff --git a/vlib/v/tests/comptime_map_part_generic_test.v b/vlib/v/tests/comptime_map_part_generic_test.v new file mode 100644 index 00000000000000..47829d0b6733af --- /dev/null +++ b/vlib/v/tests/comptime_map_part_generic_test.v @@ -0,0 +1,19 @@ +fn marshal[T](val T) string { + return marshal_map(val) +} + +fn marshal_map[T](val map[string]T) string { + return typeof(val).name +} + +fn test_main() { + assert marshal({ + 'a': 1 + }) == 'map[string]int' + assert marshal({ + 'a': true + }) == 'map[string]bool' + assert marshal({ + 'a': 1.2 + }) == 'map[string]f64' +}