cgen: fix codegen for indexing generic map (fix #23376) (#23402)

This commit is contained in:
Felipe Pena 2025-01-08 15:44:05 -03:00 committed by GitHub
parent ca48d7da37
commit f23ae9a15e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 30 deletions

View File

@ -341,15 +341,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
}
g.assign_ct_type = var_type
}
} else if val is ast.IndexExpr {
if val.left is ast.Ident && g.type_resolver.is_generic_param_var(val.left) {
ctyp := g.unwrap_generic(g.get_gn_var_type(val.left))
if ctyp != ast.void_type {
var_type = ctyp
val_type = var_type
left.obj.typ = var_type
g.assign_ct_type = var_type
}
} else if val is ast.IndexExpr && (val.left is ast.Ident && val.left.ct_expr) {
ctyp := g.unwrap_generic(g.type_resolver.get_type(val))
if ctyp != ast.void_type {
var_type = ctyp
val_type = var_type
left.obj.typ = var_type
g.assign_ct_type = var_type
}
} else if left.obj.ct_type_var == .generic_var && val is ast.CallExpr {
if val.return_type_generic != 0 && val.return_type_generic.has_flag(.generic) {

View File

@ -1353,27 +1353,6 @@ fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr) bool {
return false
}
fn (mut g Gen) get_gn_var_type(var ast.Ident) ast.Type {
if g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 {
for k, cur_param in g.cur_fn.params {
if (k == 0 && g.cur_fn.is_method) || !cur_param.typ.has_flag(.generic)
|| var.name != cur_param.name {
continue
}
mut typ := cur_param.typ
mut cparam_type_sym := g.table.sym(g.unwrap_generic(typ))
if cparam_type_sym.kind == .array {
typ = g.unwrap_generic((cparam_type_sym.info as ast.Array).elem_type)
} else if cparam_type_sym.kind == .array_fixed {
typ = g.unwrap_generic((cparam_type_sym.info as ast.ArrayFixed).elem_type)
}
return typ
}
}
return ast.void_type
}
// resolve_return_type resolves the generic return type of CallExpr
fn (mut g Gen) resolve_return_type(node ast.CallExpr) ast.Type {
if node.is_method {

View File

@ -0,0 +1,27 @@
module main
fn validate[T](values map[string]T, rules map[string][]string) ! {
for key, _ in rules {
value := values[key]!
assert typeof(value).name == T.name
}
}
fn test_main() {
validate({
'age': 31
}, {
'age': [
'required',
]
}) or { assert false }
validate({
'foo': 'bar'
}, {
'foo': [
'required',
]
}) or { assert false }
assert true
}