From 18ec24dd53bc8a6ba7f6a5013d596dd6c7a2ca7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Fri, 11 Dec 2020 04:48:55 +0100 Subject: [PATCH] gen: fix mutable map generation (#7251) --- TESTS.md | 1 + vlib/v/gen/cgen.v | 9 +++++---- vlib/v/tests/map_mut_fn_test.v | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/map_mut_fn_test.v diff --git a/TESTS.md b/TESTS.md index 5cb1e35ba8..8032cfbd93 100644 --- a/TESTS.md +++ b/TESTS.md @@ -10,6 +10,7 @@ particularly useful for checking that errors are printed. Tip: use `v -cc tcc` when compiling tests for speed. + ## `v test-compiler` This builds and tests: diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 3f6dccb243..a4f6eb941b 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1235,16 +1235,17 @@ fn (mut g Gen) for_in(it ast.ForInStmt) { idx := g.new_tmp_var() atmp := g.new_tmp_var() atmp_styp := g.typ(it.cond_type) + arw_or_pt := if it.cond_type.nr_muls() > 0 { '->' } else { '.' } g.write('$atmp_styp $atmp = ') g.expr(it.cond) g.writeln(';') - g.writeln('for (int $idx = 0; $idx < ${atmp}.key_values.len; ++$idx) {') + g.writeln('for (int $idx = 0; $idx < $atmp${arw_or_pt}key_values.len; ++$idx) {') // TODO: don't have this check when the map has no deleted elements - g.writeln('\tif (!DenseArray_has_index(&${atmp}.key_values, $idx)) {continue;}') + g.writeln('\tif (!DenseArray_has_index(&$atmp${arw_or_pt}key_values, $idx)) {continue;}') if it.key_var != '_' { key_styp := g.typ(it.key_type) key := c_name(it.key_var) - g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&${atmp}.key_values, $idx);') + g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&$atmp${arw_or_pt}key_values, $idx);') // TODO: analyze whether it.key_type has a .clone() method and call .clone() for all types: if it.key_type == table.string_type { g.writeln('\t$key = string_clone($key);') @@ -1260,7 +1261,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) { val_styp := g.typ(it.val_type) g.write('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)') } - g.writeln('DenseArray_value(&${atmp}.key_values, $idx));') + g.writeln('DenseArray_value(&$atmp${arw_or_pt}key_values, $idx));') } g.stmts(it.stmts) if it.key_type == table.string_type && !g.is_builtin_mod { diff --git a/vlib/v/tests/map_mut_fn_test.v b/vlib/v/tests/map_mut_fn_test.v new file mode 100644 index 0000000000..f1cc141eef --- /dev/null +++ b/vlib/v/tests/map_mut_fn_test.v @@ -0,0 +1,20 @@ +fn print_all(mut m map[string]string) { + for k, v in m { + println(k) + println(v) + m[k] = 'foo' + } + assert m['test'] == 'foo' +} + +fn test_map_mutable_arg() { + mut m := map[string]string{} + m['test'] = 'test' + + for k, v in m { + println(k) + println(v) + } + + print_all(mut m) +}