Skip to content

Commit 03365f5

Browse files
willtebbuttKristofferC
authored and
KristofferC
committed
fix deepcopy for non-trivial circular references (#56990)
Resolves #56775 . Credit for this fix rests entirely with bbrehm . --------- Co-authored-by: Lilith Orion Hafner <[email protected]> Co-authored-by: Neven Sajko <[email protected]> (cherry picked from commit 1ebacac)
1 parent 115ce5a commit 03365f5

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

base/deepcopy.jl

+5-2
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,14 @@ function _deepcopy_memory_t(@nospecialize(x::Memory), T, stackdict::IdDict)
120120
end
121121
return dest
122122
end
123-
@eval function deepcopy_internal(x::Array{T, N}, stackdict::IdDict) where {T, N}
123+
function deepcopy_internal(x::Array{T, N}, stackdict::IdDict) where {T, N}
124124
if haskey(stackdict, x)
125125
return stackdict[x]::typeof(x)
126126
end
127-
stackdict[x] = $(Expr(:new, :(Array{T, N}), :(deepcopy_internal(x.ref, stackdict)), :(x.size)))
127+
y = stackdict[x] = Array{T, N}(undef, ntuple(Returns(0), Val{N}()))
128+
setfield!(y, :ref, deepcopy_internal(x.ref, stackdict))
129+
setfield!(y, :size, x.size)
130+
y
128131
end
129132
function deepcopy_internal(x::GenericMemoryRef, stackdict::IdDict)
130133
if haskey(stackdict, x)

test/copy.jl

+9
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,15 @@ end
251251
@test copyto!(s, String[]) == [1, 2] # No error
252252
end
253253

254+
@testset "circular reference arrays" begin
255+
# issue 56775
256+
p = Any[nothing]
257+
p[1] = p
258+
p2 = deepcopy(p)
259+
@test p2 === p2[1]
260+
@test p2 !== p
261+
end
262+
254263
@testset "deepcopy_internal arrays" begin
255264
@test (@inferred Base.deepcopy_internal(zeros(), IdDict())) == zeros()
256265
end

0 commit comments

Comments
 (0)