cgen,checker: fix map generic fn arg passing (#22071)

This commit is contained in:
Felipe Pena 2024-08-19 21:40:37 -03:00 committed by GitHub
parent 8afadfc605
commit cf0fb835e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 23 deletions

View File

@ -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) mut ctyp := c.comptime.get_comptime_var_type(call_arg.expr)
if ctyp != ast.void_type { if ctyp != ast.void_type {
arg_sym := c.table.sym(ctyp) 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) 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 ctyp = arg_sym.info.elem_type
} else if arg_sym.info is ast.Map && param_typ.has_flag(.generic) } else if arg_sym.info is ast.Map && param_typ.has_flag(.generic)
&& c.table.final_sym(param_typ).kind == .map { && param_sym.info is ast.Map {
map_info := c.table.final_sym(param_typ).info as ast.Map if param_sym.info.key_type.has_flag(.generic) {
key_is_generic := map_info.key_type.has_flag(.generic)
if key_is_generic {
ctyp = c.unwrap_generic(arg_sym.info.key_type) ctyp = c.unwrap_generic(arg_sym.info.key_type)
} if param_sym.info.value_type.has_flag(.generic) {
if map_info.value_type.has_flag(.generic) {
if key_is_generic {
comptime_args[k] = ctyp comptime_args[k] = ctyp
k++ 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 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 { if ctyp != ast.void_type {
arg_sym := c.table.final_sym(call_arg.typ) arg_sym := c.table.final_sym(call_arg.typ)
param_typ_sym := c.table.sym(param_typ) param_typ_sym := c.table.sym(param_typ)
if param_typ.has_flag(.variadic) { if param_typ.has_flag(.variadic) {
ctyp = ast.mktyp(ctyp) ctyp = ast.mktyp(ctyp)
comptime_args[k] = 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)) cparam_type_sym := c.table.sym(c.unwrap_generic(ctyp))
if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array { if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array {
comptime_args[k] = cparam_type_sym.info.elem_type 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 { && cparam_type_sym.info is ast.Map {
comptime_args[k] = cparam_type_sym.info.key_type key_is_generic := param_typ_sym.info.key_type.has_flag(.generic)
comptime_args[k + 1] = cparam_type_sym.info.value_type if key_is_generic {
k++ 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 { } else {
if node_.args[i].expr.is_auto_deref_var() { if node_.args[i].expr.is_auto_deref_var() {
ctyp = ctyp.deref() ctyp = ctyp.deref()

View File

@ -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)) cparam_type_sym := g.table.sym(g.unwrap_generic(ctyp))
if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array { if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array {
comptime_args[k] = cparam_type_sym.info.elem_type 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 { && cparam_type_sym.info is ast.Map {
comptime_args[k] = cparam_type_sym.info.key_type if param_typ_sym.info.key_type.has_flag(.generic) {
comptime_args[k + 1] = cparam_type_sym.info.value_type comptime_args[k] = cparam_type_sym.info.key_type
k++ 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 { } else {
if node_.args[i].expr.is_auto_deref_var() { if node_.args[i].expr.is_auto_deref_var() {
ctyp = ctyp.deref() 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) { && param_typ.has_flag(.generic) {
comptime_sym := g.table.sym(comptime_args[k]) comptime_sym := g.table.sym(comptime_args[k])
if comptime_sym.info is ast.Map { if comptime_sym.info is ast.Map {
key_is_generic := param_sym.info.key_type.has_flag(.generic) if param_sym.info.key_type.has_flag(.generic) {
if key_is_generic {
comptime_args[k] = comptime_sym.info.key_type comptime_args[k] = comptime_sym.info.key_type
} if param_sym.info.value_type.has_flag(.generic) {
if param_sym.info.value_type.has_flag(.generic) {
if key_is_generic {
k++ 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 comptime_args[k] = comptime_sym.info.value_type
} }
} }

View File

@ -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'
}