What happened here is that julia has a package called OffsetArrays.jl which can be used to create arrays with arbitrary index offsets. Julia arrays start at index 1 (1-based indexing), but with OffsetArrays you could make 0-based arrays, or 10-based arrays or whatever you want.
There happened to be a bunch of code laying around which was older than OffsetArrays.jl and did things like
function f(v::AbstractVector)
for i in 1:length(v)
@inbounds do_something(v[i])
end
end
which implictly assumed that all abstract vectors could be indexed according to normal 1-based indexing rules. This created a lot of silent problems when people then went and fed offset arrays into functions that were using such incorrect indexing schemes.Instead, modern julia code that works on AbstractArray is supposed to be written using functions like eachindex, or axes, i.e.
function f(v::AbstractVector)
for i in eachindex(v)
@inbounds do_something(v[i])
end
end
though Julia's compiler is now smart enough that using @inbounds like this is typically unnecessary, since it can see that eachindex(v) can't produce an out-of-bounds index.The problematic code was incorrectly saying it worked on any subtype of AbstractArray, but was actually written assuming that the arrays were 1-based which is an invalid assumption.
Oh, that explains it. I thought it enabled a bounds check that somehow allowed code to run rather than fault. So it is a promise to the compiler that the code is correct and doesn't need checking. Composition with arbitrary bounds silently breaks that promise. Go it.