Skip to content

Commit f2d56c7

Browse files
N5N3KristofferC
authored andcommitted
SubArray: avoid invalid elimination of singleton indices (#53228)
close #53209 (cherry picked from commit 4d0a469)
1 parent 25827a4 commit f2d56c7

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

base/subarray.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ _maybe_reshape_parent(A::AbstractArray, ::NTuple{1, Bool}) = reshape(A, Val(1))
127127
_maybe_reshape_parent(A::AbstractArray{<:Any,1}, ::NTuple{1, Bool}) = reshape(A, Val(1))
128128
_maybe_reshape_parent(A::AbstractArray{<:Any,N}, ::NTuple{N, Bool}) where {N} = A
129129
_maybe_reshape_parent(A::AbstractArray, ::NTuple{N, Bool}) where {N} = reshape(A, Val(N))
130+
# The trailing singleton indices could be eliminated after bounds checking.
131+
rm_singleton_indices(ndims::Tuple, J1, Js...) = (J1, rm_singleton_indices(IteratorsMD._splitrest(ndims, index_ndims(J1)), Js...)...)
132+
rm_singleton_indices(::Tuple{}, ::ScalarIndex, Js...) = rm_singleton_indices((), Js...)
133+
rm_singleton_indices(::Tuple) = ()
134+
130135
"""
131136
view(A, inds...)
132137
@@ -173,15 +178,12 @@ julia> view(2:5, 2:3) # returns a range as type is immutable
173178
3:4
174179
```
175180
"""
176-
function view(A::AbstractArray{<:Any,N}, I::Vararg{Any,M}) where {N,M}
181+
function view(A::AbstractArray, I::Vararg{Any,M}) where {M}
177182
@inline
178183
J = map(i->unalias(A,i), to_indices(A, I))
179184
@boundscheck checkbounds(A, J...)
180-
if length(J) > ndims(A) && J[N+1:end] isa Tuple{Vararg{Int}}
181-
# view([1,2,3], :, 1) does not need to reshape
182-
return unsafe_view(A, J[1:N]...)
183-
end
184-
unsafe_view(_maybe_reshape_parent(A, index_ndims(J...)), J...)
185+
J′ = rm_singleton_indices(ntuple(Returns(true), Val(ndims(A))), J...)
186+
unsafe_view(_maybe_reshape_parent(A, index_ndims(J′...)), J′...)
185187
end
186188

187189
# Ranges implement getindex to return recomputed ranges; use that for views, too (when possible)

test/subarray.jl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,13 +762,20 @@ end
762762

763763
@testset "issue #41221: view(::Vector, :, 1)" begin
764764
v = randn(3)
765-
@test view(v,:,1) == v
766-
@test parent(view(v,:,1)) === v
767-
@test parent(view(v,2:3,1,1)) === v
765+
@test @inferred(view(v,:,1)) == v
766+
@test parent(@inferred(view(v,:,1))) === v
767+
@test parent(@inferred(view(v,2:3,1,1))) === v
768768
@test_throws BoundsError view(v,:,2)
769769
@test_throws BoundsError view(v,:,1,2)
770770

771771
m = randn(4,5).+im
772772
@test view(m, 1:2, 3, 1, 1) == m[1:2, 3]
773773
@test parent(view(m, 1:2, 3, 1, 1)) === m
774774
end
775+
776+
@testset "issue #53209: avoid invalid elimination of singleton indices" begin
777+
A = randn(4,5)
778+
@test A[CartesianIndices(()), :, 3] == @inferred(view(A, CartesianIndices(()), :, 3))
779+
@test parent(@inferred(view(A, :, 3, 1, CartesianIndices(()), 1))) === A
780+
@test_throws BoundsError view(A, :, 3, 2, CartesianIndices(()), 1)
781+
end

0 commit comments

Comments
 (0)