Allocations with recursive function using kwargs and a callback

Adding the type parameter T here helps

function recur1(func::T, l=0; kwargs...) where T # Causes no allocations
    if test(l; kwargs...)
        return func(l)
    end
    recur1(func, l+1; kwargs...)
end

julia> @time recur1(identity, limit=1)
  0.000001 seconds
1

julia> @time recur1(identity, limit=2)
  0.000001 seconds
2

julia> @time recur1(identity, limit=100)
  0.000002 seconds
100

I figured this out using AllocCheck.jl:

julia> AllocCheck.check_allocs(recur1, (typeof(identity),))
2-element Vector{Any}:
 Allocation of Int64 in /tmp/allocs.jl:7
  | recur1(func, l+1; kwargs...)

Stacktrace:
 [1] recur1(func::typeof(identity), l::Int64; kwargs::@Kwargs{})
   @ Main /tmp/allocs.jl:7
 [2] recur1
   @ /tmp/allocs.jl:3 [inlined]
 [3] #recur1#12
   @ /tmp/allocs.jl:7 [inlined]
 [4] recur1
   @ /tmp/allocs.jl:3 [inlined]
 [5] recur1(func::typeof(identity))
   @ Main /tmp/allocs.jl:3

 Dynamic dispatch to function recur1 in /tmp/allocs.jl:7
  | recur1(func, l+1; kwargs...)

Stacktrace:
 [1] recur1(func::typeof(identity), l::Int64; kwargs::@Kwargs{})
   @ Main /tmp/allocs.jl:7
 [2] recur1
   @ /tmp/allocs.jl:3 [inlined]
 [3] #recur1#12
   @ /tmp/allocs.jl:7 [inlined]
 [4] recur1
   @ /tmp/allocs.jl:3 [inlined]
 [5] recur1(func::typeof(identity))
   @ Main /tmp/allocs.jl:3

or in a screenshot for nicer highlighting:

which after adding the type parameter becomes

julia> check_allocs(recur1, (typeof(identity),))
Any[]