It’s not actually a question of unrolling, but rather a question of the fieldnames being known at compile time. For some reason, the compiler devs have decided that fieldnames shouldn’t be treated as a pure function by the compiler, even though it’s information that cannot be changed.
So unfortunately, you will need to use a generated function for this if you want efficient behaviour. Just obtaining the fieldnames is slow.
julia> struct Foo
f1::Int
f2::Int
f4::Int
end
julia> @btime fieldnames($Foo)
389.599 ns (1 allocation: 32 bytes)
(:f1, :f2, :f4)
A change to this was proposed in Pure fieldnames by bramtayl · Pull Request #30152 · JuliaLang/julia · GitHub, but one point that was raised against it was
We discourage usage of this API, and generally state that the fields of a type are an internal/private property in most cases and that users should define a function-based API (incl. accessors, getindex/keys, getproperty/propertynames, etc.)
Personally, I think this should be revisited, but in the meantime you’ll either need a generated function to make this work, or to change your approach.