From 34ecea37ceabcbdd214a0413b6491cd39efdb2e6 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 29 May 2026 04:37:34 +0300 Subject: [PATCH] markused: keep structs used by __offsetof --- vlib/v/markused/walker.v | 4 ++- vlib/v/tests/pointers/offsetof_test.v | 20 +++++++++++ .../generic_fn_instantiation_pruning_test.v | 33 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 64a16746e..d1ade5980 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -1518,7 +1518,9 @@ fn (mut w Walker) expr(node_ ast.Expr) { w.uses_lock = true w.stmts(node.stmts) } - ast.OffsetOf {} + ast.OffsetOf { + w.mark_by_type(w.resolve_current_specialized_type(node.struct_type)) + } ast.OrExpr { w.or_block(node) } diff --git a/vlib/v/tests/pointers/offsetof_test.v b/vlib/v/tests/pointers/offsetof_test.v index 3d9d66349..1a317665f 100644 --- a/vlib/v/tests/pointers/offsetof_test.v +++ b/vlib/v/tests/pointers/offsetof_test.v @@ -6,8 +6,20 @@ struct Cat { age int } +struct OffsetInlineOnly { + a int + b int +} + +struct OffsetConstOnly { + a int + b int +} + type Feline = Cat +const offset_const_only_b = __offsetof(OffsetConstOnly, b) + fn test_offsetof() { cat := Cat{ name: 'Cthulhu' @@ -21,6 +33,14 @@ fn test_offsetof() { } } +fn test_offsetof_inline_only_marks_struct_as_used() { + assert __offsetof(OffsetInlineOnly, b) == 4 +} + +fn test_offsetof_const_marks_struct_as_used() { + assert offset_const_only_b == 4 +} + fn test_offsetof_struct_from_another_module() { num := complex.Complex{1.0, 1.0} unsafe { diff --git a/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v b/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v index 976fee43f..545787ced 100644 --- a/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v +++ b/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v @@ -36,6 +36,39 @@ fn test_skip_unused_prunes_unused_generic_fn_instantiations() { assert !res.output.contains('VV_LOC Map_u8_int main__new_T_int(void)') } +fn test_skip_unused_keeps_generic_offsetof_struct_instantiations() { + tmp_dir := os.join_path(os.vtmp_dir(), 'v_issue_27283_generic_offsetof') + os.mkdir_all(tmp_dir) or { panic(err) } + defer { + os.rmdir_all(tmp_dir) or {} + } + source_path := os.join_path(tmp_dir, 'issue_27283_generic_offsetof.v') + binary_path := os.join_path(tmp_dir, 'issue_27283_generic_offsetof') + source := [ + 'module main', + '', + 'struct Box[T] {', + '\ta int', + '\tb T', + '}', + '', + 'fn off[T]() u32 {', + '\treturn __offsetof(Box[T], b)', + '}', + '', + 'fn main() {', + '\tprintln(off[int]())', + '\tprintln(off[string]())', + '}', + ].join('\n') + os.write_file(source_path, source) or { panic(err) } + res := + os.execute('${os.quoted_path(vexe)} -skip-unused -o ${os.quoted_path(binary_path)} ${os.quoted_path(source_path)}') + if res.exit_code != 0 { + panic(res.output) + } +} + fn test_skip_unused_does_not_emit_impl_methods_for_interface_extensions() { tmp_dir := os.join_path(os.vtmp_dir(), 'v_skip_unused_interface_extension_collision') os.mkdir_all(tmp_dir) or { panic(err) } -- 2.39.5