Skip to content

Commit cab83c5

Browse files
authored
Ensure that collect(::AbstractArray) always returns an Array (#21257)
The docstring specifies that the return type is `Array`, but `similar` isn't guaranteed to return an `Array`. (Exceptions include AxisArrays, OffsetArrays, etc.)
1 parent 28255c5 commit cab83c5

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

base/array.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ julia> collect(1:2:13)
383383
"""
384384
collect(itr) = _collect(1:1 #= Array =#, itr, iteratoreltype(itr), iteratorsize(itr))
385385

386+
collect(A::AbstractArray) = _collect_indices(indices(A), A)
387+
386388
collect_similar(cont, itr) = _collect(cont, itr, iteratoreltype(itr), iteratorsize(itr))
387389

388390
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
@@ -396,6 +398,14 @@ function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
396398
return a
397399
end
398400

401+
_collect_indices(::Tuple{}, A) = copy!(Array{eltype(A)}(), A)
402+
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
403+
copy!(Array{eltype(A)}(length.(indsA)), A)
404+
function _collect_indices(indsA, A)
405+
B = Array{eltype(A)}(length.(indsA))
406+
copy!(B, CartesianRange(indices(B)), A, CartesianRange(indsA))
407+
end
408+
399409
if isdefined(Core, :Inference)
400410
_default_eltype(itrt::ANY) = Core.Inference.return_type(first, Tuple{itrt})
401411
else

test/offsetarray.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ v = OffsetArray(v0, (-3,))
281281
@test endof(v) == 1
282282
@test v v
283283
@test indices(v') === (Base.OneTo(1),-2:1)
284+
@test parent(v) == collect(v)
284285
rv = reverse(v)
285286
@test indices(rv) == indices(v)
286287
@test rv[1] == v[-2]
@@ -294,6 +295,7 @@ A = OffsetArray(rand(4,4), (-3,5))
294295
@test A A
295296
@test indices(A') === (6:9, -2:1)
296297
@test parent(A') == parent(A)'
298+
@test collect(A) == parent(A)
297299
@test maximum(A) == maximum(parent(A))
298300
@test minimum(A) == minimum(parent(A))
299301
@test extrema(A) == extrema(parent(A))

0 commit comments

Comments
 (0)