diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 3f05551496..31de25738d 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 0000000000..a9bd5b9d68 --- /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 d9eed256dd..0bd9377228 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) {