Skip to content

Commit 1ebacac

Browse files
willtebbuttLilithHafnernsajko
authored
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]>
1 parent 4250be8 commit 1ebacac

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

Diff for: 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)

Diff for: test/copy.jl

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

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

0 commit comments

Comments
 (0)