-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
I've come across the following weird bug. It occurs in the branch popat-bug
of my package SmallCollections.jl:
julia> using SmallCollections
julia> firstpopat(v, i) = first(popat(v, i))
firstpopat (generic function with 1 method)
julia> v = MutableSmallVector{16,Float64}(1:16);
julia> firstpopat(v, 1) == first(popat(v, 1))
false
(popat
is an non-mutating version of Base.popat!
. It returns the shortened vector plus the deleted value.)
The problem is that the values 12.0 and 13.0 are not in the correct order in the vector firstpopat(v, 1)
:
julia> (firstpopat(v, 1),)
([2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 13.0, 12.0, 14.0, 15.0, 16.0],)
julia> (first(popat(v, 1)),)
([2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0],)
I can reproduce the bug consistently on my laptop (see below); on other computers it doesn't show up. Also, it doesn't seem to occur for other types (Float32
, Int8
etc.), nor for shorter vectors like v = MutableSmallVector{8,Float64}(1:8)
, but it does for v = MutableSmallVector{32,Float64}(1:32)
). Julia 1.10.10 behaves correctly, Julia 1.12.0-rc1 has the bug.
The bug is triggered by the last line of the following function
@inline function popat(v::FixedVector{N,T}, i::Integer) where {N,T}
@boundscheck checkbounds(v, i)
t = ntuple(Val(N)) do j
if j < i
v[j]
elseif j < N
v[j+1]
else
default(T)
end
end
FixedVector{N,T}(t), @inbounds v[i] # without @inbounds the bug disappears
end
see https://github.com/matthias314/SmallCollections.jl/blob/008bad01e0c812984f59dfbf47414dcf14b4f4d9/src/staticvectors.jl#L125-L137. What makes this particularly weird is that the value v[i]
is subsequently ignored through first
. Maybe it's an LLVM issue.
Laptop info:
Julia Version 1.11.6
Commit 9615af0f269 (2025-07-09 12:58 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 4 × Intel(R) Core(TM) i3-10110U CPU @ 2.10GHz
WORD_SIZE: 64
LLVM: libLLVM-16.0.6 (ORCJIT, skylake)