From 38a1db2f77fddb9da4c80f7218608e18d6f79e76 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 26 Oct 2017 19:21:39 -0400 Subject: [PATCH] remove fallback `hash` method. fixes #12198 --- base/atomics.jl | 2 +- base/dates/io.jl | 4 ++-- base/deprecated.jl | 2 +- base/hashing.jl | 11 +++++------ base/markdown/parse/config.jl | 2 +- base/repl/LineEdit.jl | 2 +- base/show.jl | 4 ++-- test/dict.jl | 1 + 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/base/atomics.jl b/base/atomics.jl index 51c6964a13e164..81a70eb47b1aca 100644 --- a/base/atomics.jl +++ b/base/atomics.jl @@ -316,7 +316,7 @@ function atomic_min! end unsafe_convert(::Type{Ptr{T}}, x::Atomic{T}) where {T} = convert(Ptr{T}, pointer_from_objref(x)) setindex!(x::Atomic{T}, v) where {T} = setindex!(x, convert(T, v)) -const llvmtypes = Dict( +const llvmtypes = ObjectIdDict( Bool => "i1", Int8 => "i8", UInt8 => "i8", Int16 => "i16", UInt16 => "i16", diff --git a/base/dates/io.jl b/base/dates/io.jl index fdff3d92043862..445551a502482f 100644 --- a/base/dates/io.jl +++ b/base/dates/io.jl @@ -267,7 +267,7 @@ const CONVERSION_SPECIFIERS = Dict{Char, Type}( # Default values are needed when a conversion specifier is used in a DateFormat for parsing # and we have reached the end of the input string. # Note: Allow `Any` value as a default to support extensibility -const CONVERSION_DEFAULTS = Dict{Type, Any}( +const CONVERSION_DEFAULTS = ObjectIdDict( Year => Int64(1), Month => Int64(1), DayOfWeekToken => Int64(0), @@ -282,7 +282,7 @@ const CONVERSION_DEFAULTS = Dict{Type, Any}( # Specifies the required fields in order to parse a TimeType # Note: Allows for addition of new TimeTypes -const CONVERSION_TRANSLATIONS = Dict{Type{<:TimeType}, Tuple}( +const CONVERSION_TRANSLATIONS = ObjectIdDict( Date => (Year, Month, Day), DateTime => (Year, Month, Day, Hour, Minute, Second, Millisecond), Time => (Hour, Minute, Second, Millisecond, Microsecond, Nanosecond), diff --git a/base/deprecated.jl b/base/deprecated.jl index 2236f3c8081d76..906b0eca45fa90 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -632,7 +632,7 @@ for (Bsig, A1sig, A2sig, gbb, funcname) in (SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), (SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!), ) - @eval let cache = Dict{Function,Function}() + @eval let cache = ObjectIdDict() global $funcname function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig) func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC) diff --git a/base/hashing.jl b/base/hashing.jl index e2847342a8c579..e9e6d5ad17f845 100644 --- a/base/hashing.jl +++ b/base/hashing.jl @@ -16,9 +16,7 @@ Typically, any type that implements `hash` should also implement its own `==` (h hash(x::Any) = hash(x, zero(UInt)) hash(w::WeakRef, h::UInt) = hash(w.value, h) -## hashing general objects ## - -hash(@nospecialize(x), h::UInt) = hash_uint(3h - object_id(x)) +hash(x::Union{Symbol,Slot}, h::UInt) = hash_uint(3h - object_id(x)) ## core data hashing functions ## @@ -67,12 +65,13 @@ end ## symbol & expression hashing ## if UInt === UInt64 - hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x83c7900696d26dc6)) + hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x83c7900696d26dc6)) + hash(x::QuoteNode, h::UInt) = hash(x.value, h + 0x2c97bf8b3de87020) else - hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x96d26dc6)) + hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x96d26dc6)) + hash(x::QuoteNode, h::UInt) = hash(x.value, h + 0x469d72af) end -hash(x::QuoteNode, h::UInt) = hash(x.value, hash(QuoteNode, h)) # hashing ranges by component at worst leads to collisions for very similar ranges const hashr_seed = UInt === UInt64 ? 0x80707b6821b70087 : 0x21b70087 diff --git a/base/markdown/parse/config.jl b/base/markdown/parse/config.jl index 14d3a7aa77a071..5c927336611522 100644 --- a/base/markdown/parse/config.jl +++ b/base/markdown/parse/config.jl @@ -10,7 +10,7 @@ end Config() = Config(Function[], Function[], InnerConfig()) -const META = Dict{Function, Dict{Symbol, Any}}() +const META = ObjectIdDict() getset(coll, key, default) = coll[key] = get(coll, key, default) diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index 43e5b494ce77eb..de3a871da87187 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -45,7 +45,7 @@ mutable struct MIState interface::ModalInterface current_mode::TextInterface aborted::Bool - mode_state::Dict + mode_state::ObjectIdDict kill_ring::Vector{String} kill_idx::Int previous_key::Vector{Char} diff --git a/base/show.jl b/base/show.jl index da6c84e11fa4f5..2c6488983221d2 100644 --- a/base/show.jl +++ b/base/show.jl @@ -738,7 +738,7 @@ function show_list(io::IO, items, sep, indent::Int, prec::Int=0, enclose_operato !first && print(io, sep) parens = !is_quoted(item) && (first && prec >= prec_power && - ((item isa Expr && item.head === :call && item.args[1] in uni_ops) || + ((item isa Expr && item.head === :call && item.args[1] isa Symbol && item.args[1] in uni_ops) || (item isa Real && item < 0))) || (enclose_operators && item isa Symbol && isoperator(item)) parens && print(io, '(') @@ -922,7 +922,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int) func = args[1] fname = isa(func,GlobalRef) ? func.name : func func_prec = operator_precedence(fname) - if func_prec > 0 || fname in uni_ops + if func_prec > 0 || (fname isa Symbol && fname in uni_ops) func = fname end func_args = args[2:end] diff --git a/test/dict.jl b/test/dict.jl index 8c0f22e383592d..06f41f4d551997 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -312,6 +312,7 @@ end mutable struct Alpha end Base.show(io::IO, ::Alpha) = print(io,"α") +Base.hash(a::Alpha, h::UInt) = xor(h, object_id(a)) @testset "issue #9463" begin sbuff = IOBuffer() io = Base.IOContext(sbuff, :limit => true, :displaysize => (10, 20))