I don’t know if this is intended, but it seems that WeakKeyDicts can contain objects, for which finalizers have been run:
C = WeakKeyDict()
mutable struct T
a::BigInt
f::Bool
function T(a::BigInt)
z = new(a)
z.f = false
C[z] = true
finalizer(z, _finalize)
return z
end
end
function _finalize(a::T)
a.f = true
end
Then one can produce for example
julia> A = [ T((BigInt(2)^i)) for i in 1:100];
julia> [ T((BigInt(3)^i)) for i in 1:1000];
julia> [ T((BigInt(3)^i)) for i in 1:1000];
julia> [ T((BigInt(3)^i)) for i in 1:1000];
julia> gc()
julia> C
WeakKeyDict{Any,Any} with 3100 entries:
Error showing value of type WeakKeyDict{Any,Any}:
ERROR: InexactError()
Stacktrace:
[1] ndigits0z(::BigInt, ::Int64) at ./gmp.jl:610
[2] ndigits at ./gmp.jl:624 [inlined]
[3] base(::Int64, ::BigInt) at ./gmp.jl:583
[4] show(::IOContext{Base.AbstractIOBuffer{Array{UInt8,1}}}, ::BigInt) at ./gmp.jl:569
[5] show_default(::IOContext{Base.AbstractIOBuffer{Array{UInt8,1}}}, ::Any) at ./show.jl:140
[6] show(::IOContext{Base.AbstractIOBuffer{Array{UInt8,1}}}, ::Any) at ./show.jl:125
[7] #sprint#228(::IOContext{Base.Terminals.TTYTerminal}, ::Function, ::Int64, ::Function, ::T, ::Vararg{T,N} where N) at ./strings/io.jl:64
[8] (::Base.#kw##sprint)(::Array{Any,1}, ::Base.#sprint, ::Int64, ::Function, ::T, ::Vararg{T,N} where N) at ./<missing>:0
[9] show(::IOContext{Base.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::WeakKeyDict{Any,Any}) at ./replutil.jl:64
[10] display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::MIME{Symbol("text/plain")}, ::WeakKeyDict{Any,Any}) at ./REPL.jl:122
[11] display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::WeakKeyDict{Any,Any}) at ./REPL.jl:125
[12] display(::WeakKeyDict{Any,Any}) at ./multimedia.jl:194
[13] eval(::Module, ::Any) at ./boot.jl:235
[14] print_response(::Base.Terminals.TTYTerminal, ::Any, ::Void, ::Bool, ::Bool, ::Void) at ./REPL.jl:144
[15] print_response(::Base.REPL.LineEditREPL, ::Any, ::Void, ::Bool, ::Bool) at ./REPL.jl:129
[16] (::Base.REPL.#do_respond#16{Bool,Base.REPL.##26#36{Base.REPL.LineEditREPL,Base.REPL.REPLHistoryProvider},Base.REPL.LineEditREPL,Base.LineEdit.Prompt})(::Base.LineEdit.MIState, ::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Bool) at ./REPL.jl:646
Note that this fails because some of the BigInt’s have been finalized. If you look at the keys of C
, you will find that the field f
is true
.
Is this intended?