-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the bug
When skip_unused is enabled (default), functions that return fixed-size arrays of custom structs (e.g., [4]MyStruct) but are never called cause C compilation errors. The V compiler generates a wrapper struct for the return type that references the custom struct, but the custom struct itself is not emitted because it's considered "unused".
This only occurs in larger codebases where skip_unused optimization has an effect.
Reproduction Steps
struct QuadVertex {
pos [2]f32
uv [2]f32
}
// This function is never called
pub fn make_quad_vertices(x f32, y f32, w f32, h f32) [4]QuadVertex {
return [
QuadVertex{pos: [x, y]!, uv: [f32(0), 0]!},
QuadVertex{pos: [x + w, y]!, uv: [f32(1), 0]!},
QuadVertex{pos: [x + w, y + h]!, uv: [f32(1), 1]!},
QuadVertex{pos: [x, y + h]!, uv: [f32(0), 1]!},
]!
}
fn main() {
// make_quad_vertices is intentionally not called
println('hello')
}Note: This may not reproduce in a small isolated file. The bug manifests in larger codebases (e.g., 57k+ lines) where skip_unused actively removes unused code.
Expected Behavior
The code should compile successfully. If a function is unused, its return type wrapper struct should either:
- Not be generated, OR
- Have its element type also generated
Current Behavior
C compilation fails with:
error: ';' expected (got "main__QuadVertex")
The generated C code contains:
// In BEGIN_array_fixed_return_structs section:
struct _v_Array_fixed_main__QuadVertex_4 {
main__QuadVertex ret_arr[4]; // ERROR: main__QuadVertex not defined!
};But main__QuadVertex is never defined because skip_unused determined it was unused.
Possible Solution
In write_array_fixed_return_types() in vlib/v/gen/c/cgen.v, skip generating wrapper structs when the element type is a non-builtin struct that isn't marked as used:
elem_sym := g.table.sym(info.elem_type)
if g.pref.skip_unused && elem_sym.kind == .struct && !elem_sym.is_builtin()
&& elem_sym.idx !in g.table.used_features.used_syms {
continue
}Additional Information/Context
- The bug only affects functions that RETURN fixed arrays of custom structs
- Functions that take fixed arrays as PARAMETERS work fine
- Using
-no-skip-unusedflag works around the issue - Builtin element types (e.g.,
[4]int,[4]f32) are not affected
V version
V 0.5.0 c3b924c
Environment details (OS name and version, etc.)
| V full version | V 0.5.0 c3b924c.c2aa96a |
|---|---|
| OS | linux, "Arch Linux" (VM) |
| Processor | 12 cpus, 64bit, little endian, AMD Ryzen Threadripper 7960X 24-Cores |
| Memory | 1.95GB/47GB |
| V executable | /home/jesusa/code/v/v/v |
| V last modified time | 2026-01-25 17:52:50 |
| V home dir | OK, value: /home/jesusa/code/v/v |
| VMODULES | OK, value: /home/jesusa/.vmodules |
| VTMP | OK, value: /tmp/v_1000 |
| Current working dir | OK, value: /home/jesusa/code/v/vrasta |
| Git version | git version 2.52.0 |
| V git status | weekly.2026.04-20-gc2aa96a2-dirty |
| .git/config present | true |
| cc version | cc (GCC) 15.2.1 20260103 |
| gcc version | gcc (GCC) 15.2.1 20260103 |
| clang version | clang version 21.1.6 |
| tcc version | tcc version 0.9.28rc 2025-02-13 HEAD@f8bd136d (x86_64 Linux) |
| tcc git status | thirdparty-linux-amd64 696c1d84 |
| emcc version | N/A |
| glibc version | ldd (GNU libc) 2.42 |
Note
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.