From 7c780ed8fa89c33e677020b6a0b93dd472932514 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 30 Aug 2025 17:40:47 -0300 Subject: [PATCH] cgen, markused, checker: fix iteration over mutable option (fix #24860) (#25199) --- vlib/v/checker/for.v | 3 +++ vlib/v/gen/c/assign.v | 12 +++++++++++- vlib/v/markused/walker.v | 4 ++++ vlib/v/tests/options/option_for_mut_test.v | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/options/option_for_mut_test.v diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 1643ac172..bb68ef989 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -254,6 +254,9 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { } if node.val_is_mut { value_type = value_type.ref() + if value_type.has_flag(.option) { + value_type = value_type.set_flag(.option_mut_param_t) + } match mut node.cond { ast.Ident { if mut node.cond.obj is ast.Var { diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 9f5d7f94e..2b4a15843 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -866,9 +866,19 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { g.write('*') } if node_.op == .assign && var_type.has_flag(.option_mut_param_t) { + if val is ast.CastExpr { + g.expr(left) + g.write('->state = ') + g.expr(val) + g.writeln('.state;') + } g.write('memcpy(&') g.expr(left) - g.write('->data, *(${g.styp(val_type)}**)&') + if val is ast.CastExpr { + g.write('->data, ') + } else { + g.write('->data, *(${g.styp(val_type)}**)&') + } } else if var_type.has_flag(.option_mut_param_t) { g.expr(left) g.write(' = ') diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index a7a286a72..f378d4244 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -1300,6 +1300,10 @@ fn (mut w Walker) mark_resource_dependencies() { w.fn_by_name(builderptr_idx + '.write_string') w.fn_by_name('strings.new_builder') w.uses_free[ast.string_type] = true + + if w.table.dumps.keys().any(ast.Type(u32(it)).has_flag(.option)) { + w.fn_by_name('str_intp') + } } if w.features.auto_str_ptr { w.fn_by_name('isnil') diff --git a/vlib/v/tests/options/option_for_mut_test.v b/vlib/v/tests/options/option_for_mut_test.v new file mode 100644 index 000000000..37650f5f5 --- /dev/null +++ b/vlib/v/tests/options/option_for_mut_test.v @@ -0,0 +1,15 @@ +module main + +fn test_main() { + mut data := [3]?int{} + + for mut d in data { + d = ?int(1) + assert '${d}' == 'Option(1)' + } + + for i in 0 .. data.len { + data[i] = ?int(3) + } + assert '${data}' == '[Option(3), Option(3), Option(3)]' +} -- 2.39.5