Skip to content

Commit 4917cb7

Browse files
mkittiKristofferC
authored and
KristofferC
committed
Fix push! for OffsetVectors, add tests for push! and append! on AbstractVector (#55480)
Per #55470 (comment), the `push!(::AbstractArray, ...)` array implementation assumed one-based indexing and did not account for an `OffsetVector` scenario. Here we add tests for `push!(::AbstractArray, ...)` and `append(::AbstractArray, ...)` including using `@invoke` to test the effect on `OffsetVector`. cc: @fredrikekre
1 parent ed181e7 commit 4917cb7

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

base/abstractarray.jl

+4-3
Original file line numberDiff line numberDiff line change
@@ -3532,24 +3532,25 @@ function push!(a::AbstractVector{T}, item) where T
35323532
itemT = item isa T ? item : convert(T, item)::T
35333533
new_length = length(a) + 1
35343534
resize!(a, new_length)
3535-
a[new_length] = itemT
3535+
a[end] = itemT
35363536
return a
35373537
end
35383538

35393539
# specialize and optimize the single argument case
35403540
function push!(a::AbstractVector{Any}, @nospecialize x)
35413541
new_length = length(a) + 1
35423542
resize!(a, new_length)
3543-
a[new_length] = x
3543+
a[end] = x
35443544
return a
35453545
end
35463546
function push!(a::AbstractVector{Any}, @nospecialize x...)
35473547
@_terminates_locally_meta
35483548
na = length(a)
35493549
nx = length(x)
35503550
resize!(a, na + nx)
3551+
e = lastindex(a) - nx
35513552
for i = 1:nx
3552-
a[na+i] = x[i]
3553+
a[e+i] = x[i]
35533554
end
35543555
return a
35553556
end

test/abstractarray.jl

+17-1
Original file line numberDiff line numberDiff line change
@@ -1437,14 +1437,30 @@ using .Main.OffsetArrays
14371437
end
14381438

14391439
@testset "Check push!($a, $args...)" for
1440-
a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)),
1440+
a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), SimpleArray{Any}(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)),
14411441
args in (("eenie",), ("eenie", "minie"), ("eenie", "minie", "mo"))
14421442
orig = copy(a)
14431443
push!(a, args...)
14441444
@test length(a) == length(orig) + length(args)
1445+
@test a[axes(orig,1)] == orig
14451446
@test all(a[end-length(args)+1:end] .== args)
14461447
end
14471448

1449+
@testset "Check append!($a, $args)" for
1450+
a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), SimpleArray{Any}(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)),
1451+
args in (("eenie",), ("eenie", "minie"), ("eenie", "minie", "mo"))
1452+
orig = copy(a)
1453+
append!(a, args)
1454+
@test length(a) == length(orig) + length(args)
1455+
@test a[axes(orig,1)] == orig
1456+
@test all(a[end-length(args)+1:end] .== args)
1457+
end
1458+
1459+
@testset "Check sizehint!($a)" for
1460+
a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), SimpleArray{Any}(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1))
1461+
@test sizehint!(a, 10) === a
1462+
end
1463+
14481464
@testset "splatting into hvcat" begin
14491465
t = (1, 2)
14501466
@test [t...; 3 4] == [1 2; 3 4]

test/offsetarray.jl

+29
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,18 @@ v2 = copy(v)
383383
@test v2[end-1] == 2
384384
@test v2[end] == 1
385385

386+
# push!(v::AbstractVector, x...)
387+
v2 = copy(v)
388+
@test @invoke(push!(v2::AbstractVector, 3)) === v2
389+
@test v2[axes(v,1)] == v
390+
@test v2[end] == 3
391+
@test v2[begin] == v[begin] == v[-2]
392+
v2 = copy(v)
393+
@test @invoke(push!(v2::AbstractVector, 5, 6)) == v2
394+
@test v2[axes(v,1)] == v
395+
@test v2[end-1] == 5
396+
@test v2[end] == 6
397+
386398
# append! from array
387399
v2 = copy(v)
388400
@test append!(v2, [2, 1]) === v2
@@ -399,6 +411,23 @@ v2 = copy(v)
399411
@test v2[axes(v, 1)] == v
400412
@test v2[lastindex(v)+1:end] == [2, 1]
401413

414+
# append!(::AbstractVector, ...)
415+
# append! from array
416+
v2 = copy(v)
417+
@test @invoke(append!(v2::AbstractVector, [2, 1]::Any)) === v2
418+
@test v2[axes(v, 1)] == v
419+
@test v2[lastindex(v)+1:end] == [2, 1]
420+
# append! from HasLength iterator
421+
v2 = copy(v)
422+
@test @invoke(append!(v2::AbstractVector, (v for v in [2, 1])::Any)) === v2
423+
@test v2[axes(v, 1)] == v
424+
@test v2[lastindex(v)+1:end] == [2, 1]
425+
# append! from SizeUnknown iterator
426+
v2 = copy(v)
427+
@test @invoke(append!(v2::AbstractVector, (v for v in [2, 1] if true)::Any)) === v2
428+
@test v2[axes(v, 1)] == v
429+
@test v2[lastindex(v)+1:end] == [2, 1]
430+
402431
# other functions
403432
v = OffsetArray(v0, (-3,))
404433
@test lastindex(v) == 1

0 commit comments

Comments
 (0)