Skip to content

Commit 4aa0205

Browse files
committed
remove fallback hash method. fixes #12198
1 parent c2bdb1f commit 4aa0205

File tree

12 files changed

+37
-26
lines changed

12 files changed

+37
-26
lines changed

base/Enums.jl

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Base.convert(::Type{T}, x::Enum{T2}) where {T<:Integer,T2<:Integer} = convert(T,
1414
Base.write(io::IO, x::Enum{T}) where {T<:Integer} = write(io, T(x))
1515
Base.read(io::IO, ::Type{T}) where {T<:Enum} = T(read(io, Enums.basetype(T)))
1616

17+
Base.hash(x::Enum, h::UInt) = Base.hash_uint(3h - object_id(x))
18+
1719
# generate code to test whether expr is in the given set of values
1820
function membershiptest(expr, values)
1921
lo, hi = extrema(values)

base/atomics.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ function atomic_min! end
316316
unsafe_convert(::Type{Ptr{T}}, x::Atomic{T}) where {T} = convert(Ptr{T}, pointer_from_objref(x))
317317
setindex!(x::Atomic{T}, v) where {T} = setindex!(x, convert(T, v))
318318

319-
const llvmtypes = Dict(
319+
const llvmtypes = ObjectIdDict(
320320
Bool => "i1",
321321
Int8 => "i8", UInt8 => "i8",
322322
Int16 => "i16", UInt16 => "i16",

base/dates/io.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ const CONVERSION_SPECIFIERS = Dict{Char, Type}(
267267
# Default values are needed when a conversion specifier is used in a DateFormat for parsing
268268
# and we have reached the end of the input string.
269269
# Note: Allow `Any` value as a default to support extensibility
270-
const CONVERSION_DEFAULTS = Dict{Type, Any}(
270+
const CONVERSION_DEFAULTS = ObjectIdDict(
271271
Year => Int64(1),
272272
Month => Int64(1),
273273
DayOfWeekToken => Int64(0),
@@ -282,7 +282,7 @@ const CONVERSION_DEFAULTS = Dict{Type, Any}(
282282

283283
# Specifies the required fields in order to parse a TimeType
284284
# Note: Allows for addition of new TimeTypes
285-
const CONVERSION_TRANSLATIONS = Dict{Type{<:TimeType}, Tuple}(
285+
const CONVERSION_TRANSLATIONS = ObjectIdDict(
286286
Date => (Year, Month, Day),
287287
DateTime => (Year, Month, Day, Hour, Minute, Second, Millisecond),
288288
Time => (Hour, Minute, Second, Millisecond, Microsecond, Nanosecond),

base/deprecated.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ for (Bsig, A1sig, A2sig, gbb, funcname) in
632632
(SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
633633
(SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
634634
)
635-
@eval let cache = Dict{Function,Function}()
635+
@eval let cache = ObjectIdDict()
636636
global $funcname
637637
function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig)
638638
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)

base/distributed/clusterserialize.jl

+10-2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ function serialize(s::ClusterSerializer, g::GlobalRef)
9898
invoke(serialize, Tuple{AbstractSerializer, GlobalRef}, s, g)
9999
end
100100

101+
function hash_any(@nospecialize x)
102+
try
103+
return hash(x)
104+
catch
105+
return object_id(x)
106+
end
107+
end
108+
101109
# Send/resend a global object if
102110
# a) has not been sent previously, i.e., we are seeing this object_id for the first time, or,
103111
# b) hash value has changed or
@@ -114,7 +122,7 @@ function syms_2b_sent(s::ClusterSerializer, identifier)
114122
oid = object_id(v)
115123
if haskey(s.glbs_sent, oid)
116124
# We have sent this object before, see if it has changed.
117-
s.glbs_sent[oid] != hash(sym, hash(v)) && push!(lst, sym)
125+
s.glbs_sent[oid] != hash(sym, hash_any(v)) && push!(lst, sym)
118126
else
119127
push!(lst, sym)
120128
end
@@ -143,7 +151,7 @@ function serialize_global_from_main(s::ClusterSerializer, sym)
143151
end
144152
end
145153
end
146-
record_v && (s.glbs_sent[oid] = hash(sym, hash(v)))
154+
record_v && (s.glbs_sent[oid] = hash(sym, hash_any(v)))
147155

148156
serialize(s, isconst(Main, sym))
149157
serialize(s, v)

base/distributed/workerpool.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ mutable struct CachingPool <: AbstractWorkerPool
218218
channel::Channel{Int}
219219
workers::Set{Int}
220220

221-
# Mapping between a tuple (worker_id, f) and a remote_ref
222-
map_obj2ref::Dict{Tuple{Int, Function}, RemoteChannel}
221+
# Mapping from a tuple (worker_id, f) to a remote_ref
222+
map_obj2ref::ObjectIdDict
223223

224224
function CachingPool()
225-
wp = new(Channel{Int}(typemax(Int)), Set{Int}(), Dict{Int, Function}())
225+
wp = new(Channel{Int}(typemax(Int)), Set{Int}(), ObjectIdDict())
226226
finalizer(wp, clear!)
227227
wp
228228
end

base/hashing.jl

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ Typically, any type that implements `hash` should also implement its own `==` (h
1616
hash(x::Any) = hash(x, zero(UInt))
1717
hash(w::WeakRef, h::UInt) = hash(w.value, h)
1818

19-
## hashing general objects ##
20-
21-
hash(@nospecialize(x), h::UInt) = hash_uint(3h - object_id(x))
19+
# some types for which == and === are the same
20+
hash(x::Union{Symbol,Slot,TypeName,Method,Module,Void,Core.IntrinsicFunction}, h::UInt) = hash_uint(3h - object_id(x))
2221

2322
## core data hashing functions ##
2423

@@ -67,12 +66,13 @@ end
6766
## symbol & expression hashing ##
6867

6968
if UInt === UInt64
70-
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x83c7900696d26dc6))
69+
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x83c7900696d26dc6))
70+
hash(x::QuoteNode, h::UInt) = hash(x.value, h + 0x2c97bf8b3de87020)
7171
else
72-
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x96d26dc6))
72+
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x96d26dc6))
73+
hash(x::QuoteNode, h::UInt) = hash(x.value, h + 0x469d72af)
7374
end
7475

75-
hash(x::QuoteNode, h::UInt) = hash(x.value, hash(QuoteNode, h))
7676

7777
# hashing ranges by component at worst leads to collisions for very similar ranges
7878
const hashr_seed = UInt === UInt64 ? 0x80707b6821b70087 : 0x21b70087

base/markdown/parse/config.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ end
1010

1111
Config() = Config(Function[], Function[], InnerConfig())
1212

13-
const META = Dict{Function, Dict{Symbol, Any}}()
13+
const META = ObjectIdDict()
1414

1515
getset(coll, key, default) = coll[key] = get(coll, key, default)
1616

base/reflection.jl

+6-6
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ function instances end
507507

508508
# subtypes
509509
function _subtypes(m::Module, x::Union{DataType,UnionAll},
510-
sts=Set{Union{DataType,UnionAll}}(), visited=Set{Module}())
510+
sts=ObjectIdDict(), visited=Set{Module}())
511511
push!(visited, m)
512512
xt = unwrap_unionall(x)
513513
if !isa(xt, DataType)
@@ -521,7 +521,7 @@ function _subtypes(m::Module, x::Union{DataType,UnionAll},
521521
t = t::DataType
522522
if t.name.name === s && supertype(t).name == xt.name
523523
ti = typeintersect(t, x)
524-
ti != Bottom && push!(sts, ti)
524+
ti != Bottom && push!(sts, ti=>true)
525525
end
526526
elseif isa(t, UnionAll)
527527
t = t::UnionAll
@@ -530,7 +530,7 @@ function _subtypes(m::Module, x::Union{DataType,UnionAll},
530530
tt = tt::DataType
531531
if tt.name.name === s && supertype(tt).name == xt.name
532532
ti = typeintersect(t, x)
533-
ti != Bottom && push!(sts, ti)
533+
ti != Bottom && push!(sts, ti=>true)
534534
end
535535
elseif isa(t, Module)
536536
t = t::Module
@@ -544,14 +544,14 @@ end
544544
function _subtypes_in(mods::Array, x::Union{DataType,UnionAll})
545545
if !isabstract(x)
546546
# Fast path
547-
return Union{DataType,UnionAll}[]
547+
return Any[]
548548
end
549-
sts = Set{Union{DataType,UnionAll}}()
549+
sts = ObjectIdDict()
550550
visited = Set{Module}()
551551
for m in mods
552552
_subtypes(m, x, sts, visited)
553553
end
554-
return sort!(collect(sts), by=string)
554+
return sort!(collect(Any, keys(sts)), by=string)
555555
end
556556

557557
subtypes(m::Module, x::Union{DataType,UnionAll}) = _subtypes_in([m], x)

base/repl/LineEdit.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ mutable struct MIState
4545
interface::ModalInterface
4646
current_mode::TextInterface
4747
aborted::Bool
48-
mode_state::Dict
48+
mode_state::ObjectIdDict
4949
kill_ring::Vector{String}
5050
kill_idx::Int
5151
previous_key::Vector{Char}
@@ -1949,7 +1949,7 @@ init_state(terminal, prompt::Prompt) =
19491949
#=indent(spaces)=# -1, Threads.SpinLock(), 0.0)
19501950

19511951
function init_state(terminal, m::ModalInterface)
1952-
s = MIState(m, m.modes[1], false, Dict{Any,Any}())
1952+
s = MIState(m, m.modes[1], false, ObjectIdDict())
19531953
for mode in m.modes
19541954
s.mode_state[mode] = init_state(terminal, mode)
19551955
end

base/show.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ function show_list(io::IO, items, sep, indent::Int, prec::Int=0, enclose_operato
738738
!first && print(io, sep)
739739
parens = !is_quoted(item) &&
740740
(first && prec >= prec_power &&
741-
((item isa Expr && item.head === :call && item.args[1] in uni_ops) ||
741+
((item isa Expr && item.head === :call && item.args[1] isa Symbol && item.args[1] in uni_ops) ||
742742
(item isa Real && item < 0))) ||
743743
(enclose_operators && item isa Symbol && isoperator(item))
744744
parens && print(io, '(')
@@ -922,7 +922,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int)
922922
func = args[1]
923923
fname = isa(func,GlobalRef) ? func.name : func
924924
func_prec = operator_precedence(fname)
925-
if func_prec > 0 || fname in uni_ops
925+
if func_prec > 0 || (fname isa Symbol && fname in uni_ops)
926926
func = fname
927927
end
928928
func_args = args[2:end]

test/dict.jl

+1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ end
312312

313313
mutable struct Alpha end
314314
Base.show(io::IO, ::Alpha) = print(io,"α")
315+
Base.hash(a::Alpha, h::UInt) = xor(h, object_id(a))
315316
@testset "issue #9463" begin
316317
sbuff = IOBuffer()
317318
io = Base.IOContext(sbuff, :limit => true, :displaysize => (10, 20))

0 commit comments

Comments
 (0)