diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 2ed0451df77bb..68ed0dc0f5b68 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -355,14 +355,19 @@ module IteratorsMD # CartesianIndices act as a multidimensional range, so cartesian indexing of CartesianIndices # with compatible dimensions may be seen as indexing into the component ranges. # This may use the special indexing behavior implemented for ranges to return another CartesianIndices - @propagate_inbounds function Base.getindex(iter::CartesianIndices{N,R}, + @inline function Base.getindex(iter::CartesianIndices{N,R}, I::Vararg{Union{OrdinalRange{<:Integer, <:Integer}, Colon}, N}) where {N,R} - CartesianIndices(getindex.(iter.indices, I)) + @boundscheck checkbounds(iter, I...) + indices = map(iter.indices, I) do r, i + @inbounds getindex(r, i) + end + CartesianIndices(indices) end @propagate_inbounds function Base.getindex(iter::CartesianIndices{N}, C::CartesianIndices{N}) where {N} - CartesianIndices(getindex.(iter.indices, C.indices)) + getindex(iter, C.indices...) end + @inline Base.getindex(iter::CartesianIndices{0}, ::CartesianIndices{0}) = iter # If dimensions permit, we may index into a CartesianIndices directly instead of constructing a SubArray wrapper @propagate_inbounds function Base.view(c::CartesianIndices{N}, r::Vararg{Union{OrdinalRange{<:Integer, <:Integer}, Colon},N}) where {N} diff --git a/test/boundscheck_exec.jl b/test/boundscheck_exec.jl index 4040a2739730f..71690c55faeca 100644 --- a/test/boundscheck_exec.jl +++ b/test/boundscheck_exec.jl @@ -260,6 +260,7 @@ if bc_opt == bc_default || bc_opt == bc_off end @testset "pass inbounds meta to getindex on CartesianIndices (#42115)" begin + @inline getindex_42115(r, i) = @inbounds getindex(r, i) @inline getindex_42115(r, i, j) = @inbounds getindex(r, i, j) R = CartesianIndices((5, 5)) @@ -270,6 +271,14 @@ end @test getindex_42115(R, -1, -1) == CartesianIndex(-1, -1) @test getindex_42115(R, 1, -1) == CartesianIndex(1, -1) end + + if bc_opt == bc_on + @test_throws BoundsError getindex_42115(R, CartesianIndices((6, 6))) + @test_throws BoundsError getindex_42115(R, -1:3, :) + else + @test getindex_42115(R, CartesianIndices((6, 6))) == CartesianIndices((6, 6)) + @test getindex_42115(R, -1:3, :) == CartesianIndices((-1:3, 1:5)) + end end