From cd5459af6d4e67f805e6ee5da1a047377bf1f62b Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 13 Nov 2025 03:01:12 +0900 Subject: [PATCH] replace `MethodInfoKey` Pair alias with struct to avoid type piracy Changes `MethodInfoKey` from a `Pair` type alias to a proper struct, avoiding type piracy that would be introduced by defining `Pair{...}(::Method)` conversion methods. The struct implements `Base.iterate` to maintain compatibility with destructuring patterns. This is a breaking change as it changes the representation of method info keys, which packages like LCU and Revise depend heavily on. So we unfotunately need to bump the major version from 2 to 3. As an alternative, removing `Pair{...}(::Method)` would also be possible, but that would also break LCU and Revise, so I'm taking this approach which appears to be a better and moer complete fix. --- Project.toml | 2 +- src/CodeTracking.jl | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 1a0dfeb..fd671c0 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CodeTracking" uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" authors = ["Tim Holy "] -version = "2.0.2" +version = "3.0.0" [deps] InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" diff --git a/src/CodeTracking.jl b/src/CodeTracking.jl index a5af580..1fb6195 100644 --- a/src/CodeTracking.jl +++ b/src/CodeTracking.jl @@ -29,13 +29,27 @@ include("utils.jl") # These values get populated by Revise -# `method_info[mt => sig]` is either: +# `method_info[MethodInfoKey(mt, sig)]` is either: # - `missing`, to indicate that the method cannot be located # - a list of `(lnn,ex)` pairs. In almost all cases there will be just one of these, # but "mistakes" in moving methods from one file to another can result in more than # one definition. The last pair in the list is the currently-active definition. -const MethodInfoKey = Pair{Union{Nothing, MethodTable}, Type} +struct MethodInfoKey + mt::Union{Nothing, MethodTable} + sig::Type + MethodInfoKey(mt::Union{Nothing, MethodTable}, @nospecialize(sig::Type)) = new(mt, sig) +end + +function Base.iterate(mt_sig::MethodInfoKey, s::Union{Int,Nothing}=nothing) + if s === nothing + return mt_sig.mt, 1 + elseif s == 1 + return mt_sig.sig, 2 + else + return nothing + end +end const method_info = IdDict{MethodInfoKey,Union{Missing,Vector{Tuple{LineNumberNode,Expr}}}}()