From 36bef926fb9642378f6514886af7ce16279357f5 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 11 Jun 2025 12:57:36 -0300 Subject: [PATCH] autofree: fix codegen for comptime selector usage (fix #24655) (#24697) --- vlib/v/checker/fn.v | 2 +- .../v/slow_tests/valgrind/comptime_selector.v | 52 +++++++++++++++++++ vlib/v/slow_tests/valgrind/valgrind_test.v | 1 + 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 vlib/v/slow_tests/valgrind/comptime_selector.v diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 3f0555149..31de25738 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -731,7 +731,7 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type { if arg.typ != ast.string_type { continue } - if arg.expr in [ast.Ident, ast.StringLiteral, ast.SelectorExpr] + if arg.expr in [ast.Ident, ast.StringLiteral, ast.SelectorExpr, ast.ComptimeSelector] || (arg.expr is ast.CallExpr && arg.expr.or_block.kind != .absent) { // Simple expressions like variables, string literals, selector expressions // (`x.field`) can't result in allocations and don't need to be assigned to diff --git a/vlib/v/slow_tests/valgrind/comptime_selector.v b/vlib/v/slow_tests/valgrind/comptime_selector.v new file mode 100644 index 000000000..a9bd5b9d6 --- /dev/null +++ b/vlib/v/slow_tests/valgrind/comptime_selector.v @@ -0,0 +1,52 @@ +module main + +import encoding.binary +import math + +fn main() { + value := Vector3D{ + x: 1.0 + y: 2.0 + z: 3.0 + v: 'bob' + } + mut buf := []u8{len: 0, cap: 12} + serialize_to(value, mut buf)! + println(buf) +} + +type Primitive = f64 | f32 | rune | i32 | u32 | i16 | u16 | i8 | u8 | bool + +struct Vector3D { + x f32 + y f32 + z f32 + v string +} + +fn serialize_to[T](val T, mut output []u8) ! { + $for v in Primitive.variants { + $if v.typ is T { + output << binary.encode_binary(val, binary.EncodeConfig{ + buffer_len: int(sizeof[T]()) + big_endian: false + })! + return + } + } + $if T is string { + if val.len > math.maxof[u16]() { + return error('String too long to serialize') + } + bytes := val.bytes() + output << binary.encode_binary(u16(bytes.len), binary.EncodeConfig{ + buffer_len: int(sizeof[u16]()) + big_endian: false + })! + output << bytes + return + } + $for field in T.fields { + serialize_to(val.$(field.name), mut output)! + } +} diff --git a/vlib/v/slow_tests/valgrind/valgrind_test.v b/vlib/v/slow_tests/valgrind/valgrind_test.v index d9eed256d..0bd937722 100644 --- a/vlib/v/slow_tests/valgrind/valgrind_test.v +++ b/vlib/v/slow_tests/valgrind/valgrind_test.v @@ -32,6 +32,7 @@ const skip_valgrind_files = [ 'vlib/v/slow_tests/valgrind/option_simple.v', 'vlib/v/slow_tests/valgrind/string_plus_string_plus.v', 'vlib/v/slow_tests/valgrind/import_x_json2.v', + 'vlib/v/slow_tests/valgrind/comptime_selector.v', ] fn vprintln(s string) { -- 2.39.5