Skip to content

Commit

Permalink
cgen: fix codegen for indexing generic map (fix vlang#23376) (vlang#2…
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Jan 8, 2025
1 parent ca48d7d commit f23ae9a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 30 deletions.
16 changes: 7 additions & 9 deletions vlib/v/gen/c/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
21 changes: 0 additions & 21 deletions vlib/v/gen/c/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
27 changes: 27 additions & 0 deletions vlib/v/tests/comptime/comptime_generic_map_test.v
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit f23ae9a

Please sign in to comment.