Allocations due to Boolean keyword arguments - how to avoid them?

But then why is the second example working fine without allocations? Why is there no dynamic dispatch, even though it is the exact same flow of code?

I copy it here (it was in the <details> tag of the original post):

"""Just some contrived work function that happens to slightly change behavior depending on Val keyword"""
function simple_work_val(obj::Vector; extrawork::Val{B}=Val(true)) where B
    l = size(obj,1)
    @inbounds for i in 1:l
        @inbounds for j in i+1:l
            obj[i] ⊻= obj[j]
            if B
                obj[i] += obj[i]
            end
        end
    end
end

"""A "public interface" function that uses a Bool keyword instead of a Val keyword"""
function simple_work_bool_to_val(obj::Vector; extrawork::Bool=true)
    simple_work_val(obj; extrawork=Val(extrawork))
end

The reason for the Val{true} is that in the real non-minimal case it has noticeably different performance, presumably because it forces specialization. It is something I originally saw in this thread with examples of its use in SciML and Polyester. And here is a real world example where simply switching from Bool to Val{Bool} eliminated allocations, because of this specialization issue - the issue is that this example is rather long so I could not use it as a MWE.