From be85287632db842f5898c146a6b28c3a0814d8cb Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 7 May 2025 03:41:01 -0300 Subject: [PATCH] cgen, checker: fix for with mut generic value (fix #24360) (#24426) --- vlib/v/checker/for.v | 6 ++- vlib/v/gen/c/for.v | 3 ++ .../tests/generics/generic_for_mut_val_test.v | 42 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/generics/generic_for_mut_val_test.v diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 2b7f7df59..7f47be570 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -200,8 +200,12 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { } } - value_type := c.table.value_type(unwrapped_typ) + mut value_type := c.table.value_type(unwrapped_typ) + if node.val_is_mut { + value_type = value_type.ref() + } node.scope.update_var_type(node.val_var, value_type) + node.val_type = value_type if is_comptime { c.type_resolver.update_ct_type(node.val_var, value_type) diff --git a/vlib/v/gen/c/for.v b/vlib/v/gen/c/for.v index 16880ad47..7830c558f 100644 --- a/vlib/v/gen/c/for.v +++ b/vlib/v/gen/c/for.v @@ -154,6 +154,9 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { node.cond_type = unwrapped_typ node.val_type = g.table.value_type(unwrapped_typ) + if node.val_is_mut { + node.val_type = node.val_type.ref() + } node.scope.update_var_type(node.val_var, node.val_type) node.kind = unwrapped_sym.kind diff --git a/vlib/v/tests/generics/generic_for_mut_val_test.v b/vlib/v/tests/generics/generic_for_mut_val_test.v new file mode 100644 index 000000000..61c6e88eb --- /dev/null +++ b/vlib/v/tests/generics/generic_for_mut_val_test.v @@ -0,0 +1,42 @@ +struct ValueMenu { + name string +} + +fn (mut v ValueMenu) resp(resp []u8) { + println('menu ${v.name} ${resp}') +} + +fn value_resp[T](mut t T, r []u8) { + $if T is $array { + value_array_resp(mut t, r) + } +} + +fn value_array_resp[T](mut t T, r []u8) { + $if T is []ValueMenu { + for _, mut i in t { // mut i -> C error + i.resp(r) + } + for i := 0; i < t.len; i++ { // WORKAROUND + t[i].resp(r) + } + } +} + +struct Colors { +mut: + normal []ValueMenu = [ValueMenu{'blink'}, ValueMenu{'hue'}] +} + +fn (c &Colors) resp(resp []u8) { + $for f in c.fields { + mut m := c.$(f.name) + value_resp(mut m, resp) + } +} + +fn test_main() { + colors := &Colors{} + colors.resp([u8(0), 1, 2]) + assert true +} -- 2.39.5