Surprising Type Error

I ran into the following unexpected error using and array of CartesianIndex:

julia> c = CartesianIndex[]
CartesianIndex[]

julia> push!(c, CartesianIndex(1, 2))
1-element Array{CartesianIndex,1}:
 CartesianIndex(1, 2)

julia> M = [1 2; 3 4]
2×2 Array{Int64,2}:
 1  2
 3  4

julia> M[c]
ERROR: ArgumentError: unable to check bounds for indices of type CartesianIndex{2}
Stacktrace:
 [1] checkindex(::Type{Bool}, ::Base.OneTo{Int64}, ::CartesianIndex{2}) at ./abstractarray.jl:561
 [2] checkindex at ./abstractarray.jl:576 [inlined]
 [3] checkbounds_indices at ./abstractarray.jl:532 [inlined]
 [4] checkbounds at ./multidimensional.jl:544 [inlined]
 [5] checkbounds at ./abstractarray.jl:506 [inlined]
 [6] _getindex at ./multidimensional.jl:742 [inlined]
 [7] getindex(::Array{Int64,2}, ::Array{CartesianIndex,1}) at ./abstractarray.jl:1060
 [8] top-level scope at REPL[44]:1

However, if I iterate over the same array, I get what I expected:

julia> for x in c
           println(M[x])
       end
2

After some head scratching (and possibly some cursing), I amended the original declaration of c to c = CartesianIndex{2}[], which fixed the problem – M[c] gives the expected result of 2.

I’m a bit confused by this behavior – can someone explain what’s going on here?

3 Likes

Probably there is a getindex method for Array{T, N} that takes CartesianIndex{N}[] (i.e., a Vector of concretely typed indexes with the right dimensions) but if the Vector is not concretely typed then it probably enters a fallback that errors after.

2 Likes

Thanks for posting this. Saved me some definite cursing. Not only is this catch/bug obscure, but the error message is almost Kafkaesque.

2 Likes