You could use generated function:
@generated function getfield_unrolled(t::T, f::Symbol) where {T}
names = fieldnames(T)
exprs = [:($(QuoteNode(name)) == f && return getfield(t, $(QuoteNode(name)))) for (c, name) in enumerate(names)]
push!(exprs, :(throw(ErrorException("type $T has no field $f"))))
return quote
$(exprs...)
end
end
and get
julia> @btime getfield_unrolled($test, $(tup[1]))
1.855 ns (0 allocations: 0 bytes)
"A"