@@ -165,27 +165,62 @@ function showerror(io::IO, ex::MethodError)
165
165
print (io, " since type constructors fall back to convert methods in julia v0.4." )
166
166
end
167
167
168
- # Display up to three closest candidates
168
+ show_method_candidates (io, ex)
169
+ end
170
+
171
+ function show_method_candidates (io:: IO , ex:: MethodError )
172
+ # Displays the closest candidates of the given function by looping over the
173
+ # functions methods and counting the number of matching arguments.
169
174
lines = Array ((IOBuffer, Int), 0 )
175
+ name = isgeneric (ex. f) ? ex. f. env. name : :anonymous
170
176
for method in methods (ex. f)
171
- n = length (ex. args)
172
- if n != length (method. sig)
173
- continue
174
- end
175
177
buf = IOBuffer ()
176
- print (buf, " $(ex. f. env. name) (" )
177
- first = true
178
+ print (buf, " $name " )
178
179
right_matches = 0
179
- for (arg, sigtype) in Zip2 {Any,Any} (ex. args, method. sig)
180
- if first
181
- first = false
180
+ tv = method. tvars
181
+ if ! isa (tv,Tuple)
182
+ tv = (tv,)
183
+ end
184
+ if ! isempty (tv)
185
+ show_delim_array (buf, tv, ' {' , ' ,' , ' }' , false )
186
+ end
187
+ print (buf, " (" )
188
+ t_i = Any[typeof (ex. args)... ]
189
+ right_matches = 0
190
+ for i = 1 : min (length (t_i), length (method. sig))
191
+ i != 1 && print (buf, " , " )
192
+ # If isvarargtype then it checks wether the rest of the input arguements matches
193
+ # the varargtype
194
+ j = Base. isvarargtype (method. sig[i]) ? length (t_i) : i
195
+ # checks if the type of arg 1:i of the input intersects with the current method
196
+ t_in = typeintersect (method. sig[1 : i], tuple (t_i[1 : j]. .. ))
197
+ if t_in == None
198
+ # If there is no typeintersect then the type signature from the method is
199
+ # inserted in t_i this insures if the type at the next i matches the type
200
+ # signature then there will be a type intersect
201
+ t_i[i] = method. sig[i]
202
+ Base. with_output_color (:red , buf) do buf
203
+ print (buf, " ::$(method. sig[i]) " )
204
+ end
182
205
else
183
- print (buf, " , " )
206
+ right_matches += j== i ? 1 : 0
207
+ print (buf, " ::$(method. sig[i]) " )
184
208
end
185
- if typeof (arg) <: sigtype
186
- right_matches += 1
187
- print (buf, " ::$(sigtype) " )
188
- else
209
+ end
210
+ if length (t_i) > length (method. sig) && Base. isvarargtype (method. sig[end ])
211
+ # It insures that methods like f(a::AbstractString...) gets the correct
212
+ # number of right_matches
213
+ for t in typeof (ex. args)[length (method. sig): end ]
214
+ if t <: method.sig [end ]. parameters[1 ]
215
+ right_matches += 1
216
+ end
217
+ end
218
+ end
219
+ if length (t_i) < length (method. sig)
220
+ # If the methods args is longer than input then the method
221
+ # arguments is printed as not a match
222
+ for sigtype in method. sig[length (t_i)+ 1 : end ]
223
+ print (buf, " , " )
189
224
Base. with_output_color (:red , buf) do buf
190
225
print (buf, " ::$(sigtype) " )
191
226
end
@@ -196,7 +231,7 @@ function showerror(io::IO, ex::MethodError)
196
231
push! (lines, (buf, right_matches))
197
232
end
198
233
end
199
- if length (lines) != 0
234
+ if length (lines) != 0 # Display up to three closest candidates
200
235
Base. with_output_color (:normal , io) do io
201
236
println (io, " \n Closest candidates are:" )
202
237
sort! (lines, by = x -> - x[2 ])
0 commit comments