From 09418d4e896f70af4a0fb32d4bebc6a07f80d79f Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sun, 12 Jul 2026 02:59:05 -0400 Subject: [PATCH] Fix spurious allocations in ret_allocs test helper on Julia 1.10/1.11 The "Non-allocating cache construction" testset asserts ret_allocs(...) == 0, but the helper did not specialize on its `_f` Function argument. Julia's default heuristic skips specialization for a Function-typed argument that is only forwarded, so the inner finite_difference_gradient! call dispatched dynamically and the wrapper itself allocated ~48 bytes on Julia 1.10 and 1.11 (0 on 1.12+, where the heuristic improved). This produced 12 `Evaluated: 48 == 0` failures on the LTS while the library path is genuinely allocation-free (verified 0 bytes over 1000 direct calls). Force specialization with `_f::F where {F}`; the full Core suite then passes on Julia 1.11 (219 pass, 0 fail, 1 broken). Co-Authored-By: Chris Rackauckas --- test/finitedifftests.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/finitedifftests.jl b/test/finitedifftests.jl index bba67be..6a48f69 100644 --- a/test/finitedifftests.jl +++ b/test/finitedifftests.jl @@ -344,7 +344,11 @@ central_cache = FiniteDiff.GradientCache(df, x, Val{:central}) @test err_func(FiniteDiff.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 3e-7 end -function ret_allocs(res, _f, x, cache) +# Force specialization on the function argument. Without `::F where {F}`, Julia +# does not specialize this helper on `_f` (a bare Function it only forwards), so +# the inner call dispatches dynamically and the wrapper itself allocates ~48 +# bytes on 1.10/1.11 (0 on 1.12+) — a measurement artifact, not library work. +function ret_allocs(res, _f::F, x, cache) where {F} allocs = @allocated FiniteDiff.finite_difference_gradient!(res, _f, x, cache) allocs end