@@ -24,8 +24,8 @@ Split a signature type like `Tuple{typeof(f),ArgTypes...}` back out to `(f, Tupl
2424function call_type (tt)
2525 ft = tt. parameters[1 ]
2626 argt = Tuple{tt. parameters[2 : end ]. .. }
27- name = Symbol (String (ft. name. name)[ 2 : end ]) # strip off leading '#'
28- return (getfield (ft. name. module, name), argt)
27+ name = Symbol (String (ft. name. name))
28+ return (getfield (ft. name. module, name). instance , argt)
2929end
3030
3131"""
@@ -87,34 +87,69 @@ julia> methodinstance(Tuple{typeof(f), Int, String})
8787MethodInstance for f(::Int64, ::String)
8888```
8989"""
90- function methodinstance (@nospecialize (f), @nospecialize (types))
90+ methodinstance (@nospecialize (f), @nospecialize (types)) =
91+ _methodinstance (f, types, false )
92+
93+ function methodinstance (@nospecialize (types))
94+ f, argt = call_type (types)
95+ return methodinstance (f, types)
96+ end
97+
98+ function _methodinstance (@nospecialize (f), @nospecialize (types), multi:: Bool )
9199 if types isa Tuple
92100 tt = Tuple{typeof (f), types... }
93- return methodinstance (f, tt)
101+ return _methodinstance (f, tt, multi )
94102 end
95- inst = nothing
103+ kept = MethodInstance[]
96104 visit (f) do mi
97105 if isa (mi, MethodInstance)
98- if mi. specTypes === types
99- inst = mi
106+ if multi ? ( mi. specTypes <: types ) : (mi . specTypes === types)
107+ push! (kept, mi)
100108 end
101109 return false
102110 end
103111 true
104112 end
105- return inst
106- end
107- function methodinstance (@nospecialize (types))
108- f, argt = call_type (types)
109- return methodinstance (f, types)
113+ multi && return kept
114+ length (kept) == 1 && return kept[1 ]
115+ length (kept) == 0 && return nothing
116+ error (length (kept), " MethodInstances matched the specified types" )
110117end
111118
112119"""
113120 methodinstances()
114- methodinstances(mod::Module)
115- methodinstances(f)
121+ methodinstances(top)
116122
117123Collect all `MethodInstance`s, optionally restricting them to a particular module, function, method, or methodlist.
124+
125+ # Examples
126+
127+ ```
128+ julia> sin(π/2)
129+ 1.0
130+
131+ julia> sin(0.8f0)
132+ 0.7173561f0
133+
134+ julia> methodinstances(sin)
135+ 2-element Vector{Core.MethodInstance}:
136+ MethodInstance for sin(::Float64)
137+ MethodInstance for sin(::Float32)
138+
139+ julia> m = which(convert, (Type{Bool}, Real))
140+ convert(::Type{T}, x::Number) where T<:Number in Base at number.jl:7
141+
142+ julia> methodinstances(m)
143+ 68-element Vector{Core.MethodInstance}:
144+ MethodInstance for convert(::Type{UInt128}, ::Int64)
145+ MethodInstance for convert(::Type{Int128}, ::Int64)
146+ MethodInstance for convert(::Type{Int64}, ::Int32)
147+ MethodInstance for convert(::Type{UInt64}, ::Int64)
148+ ⋮
149+ ```
150+
151+ Note the method `m` was broader than the signature we queried with, and the returned `MethodInstance`s reflect that breadth.
152+ See [`methodinstances`](@ref) for a more restrictive subset.
118153"""
119154function methodinstances (top= ())
120155 if isa (top, Module) || isa (top, Function) || isa (top, Type) || isa (top, Method) || isa (top, Base. MethodList)
@@ -129,6 +164,32 @@ function methodinstances(top=())
129164 return mis
130165end
131166
167+ """
168+ methodinstances(f, types)
169+ methodinstances(tt::Type{<:Tuple})
170+
171+ Return all MethodInstances whose signature is a subtype of `types`.
172+
173+ # Example
174+
175+ ```
176+ julia> methodinstances(convert, (Type{Bool}, Real))
177+ 2-element Vector{Core.MethodInstance}:
178+ MethodInstance for convert(::Type{Bool}, ::Bool)
179+ MethodInstance for convert(::Type{Bool}, ::Int64)
180+ ```
181+
182+ Compare this to the result from [`methodinstance`](@ref).
183+ """
184+ methodinstances (@nospecialize (f), @nospecialize (types)) =
185+ _methodinstance (f, types, true )
186+
187+ function methodinstances (@nospecialize (types:: Type ))
188+ f, argt = call_type (types)
189+ return methodinstances (f, types)
190+ end
191+
192+
132193if isdefined (Core, :MethodMatch )
133194 include (" findcallers.jl" )
134195end
0 commit comments