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