@@ -246,14 +246,15 @@ end
246
246
function showerror (io:: IO , ex:: MethodError )
247
247
# ex.args is a tuple type if it was thrown from `invoke` and is
248
248
# a tuple of the arguments otherwise.
249
- is_arg_types = isa (ex. args, DataType)
250
- arg_types = (is_arg_types ? ex. args : typesof (ex. args... )):: DataType
249
+ is_arg_types = ! isa (ex. args, Tuple)
250
+ arg_types = is_arg_types ? ex. args : typesof (ex. args... )
251
+ arg_types_param:: SimpleVector = (unwrap_unionall (arg_types):: DataType ). parameters
252
+ san_arg_types_param = Any[rewrap_unionall (a, arg_types) for a in arg_types_param]
251
253
f = ex. f
252
254
meth = methods_including_ambiguous (f, arg_types)
253
255
if isa (meth, MethodList) && length (meth) > 1
254
256
return showerror_ambiguous (io, meth, f, arg_types)
255
257
end
256
- arg_types_param:: SimpleVector = arg_types. parameters
257
258
print (io, " MethodError: " )
258
259
ft = typeof (f)
259
260
f_is_function = false
@@ -262,10 +263,11 @@ function showerror(io::IO, ex::MethodError)
262
263
f = (ex. args:: Tuple )[2 ]
263
264
ft = typeof (f)
264
265
arg_types_param = arg_types_param[3 : end ]
266
+ san_arg_types_param = san_arg_types_param[3 : end ]
265
267
kwargs = pairs (ex. args[1 ])
266
268
ex = MethodError (f, ex. args[3 : end :: Int ], ex. world)
269
+ arg_types = Tuple{arg_types_param... }
267
270
end
268
- name = ft. name. mt. name
269
271
if f === Base. convert && length (arg_types_param) == 2 && ! is_arg_types
270
272
f_is_function = true
271
273
show_convert_error (io, ex, arg_types_param)
@@ -277,36 +279,28 @@ function showerror(io::IO, ex::MethodError)
277
279
if ft <: Function && isempty (ft. parameters) && _isself (ft)
278
280
f_is_function = true
279
281
end
280
- print (io, " no method matching " )
282
+ if is_arg_types
283
+ print (io, " no method matching invoke " )
284
+ else
285
+ print (io, " no method matching " )
286
+ end
281
287
buf = IOBuffer ()
282
288
iob = IOContext (buf, io) # for type abbreviation as in #49795; some, like `convert(T, x)`, should not abbreviate
283
289
show_signature_function (iob, isa (f, Type) ? Type{f} : typeof (f))
284
- print (iob, " (" )
285
- for (i, typ) in enumerate (arg_types_param)
286
- print (iob, " ::" , typ)
287
- i == length (arg_types_param) || print (iob, " , " )
288
- end
289
- if ! isempty (kwargs)
290
- print (iob, " ; " )
291
- for (i, (k, v)) in enumerate (kwargs)
292
- print (iob, k, " ::" , typeof (v))
293
- i == length (kwargs):: Int || print (iob, " , " )
294
- end
295
- end
296
- print (iob, " )" )
290
+ show_tuple_as_call (iob, :function , arg_types; hasfirst= false , kwargs = ! isempty (kwargs) ? Any[(k, typeof (v)) for (k, v) in kwargs] : nothing )
297
291
str = String (take! (buf))
298
292
str = type_limited_string_from_context (io, str)
299
293
print (io, str)
300
294
end
301
295
# catch the two common cases of element-wise addition and subtraction
302
- if (f === Base.:+ || f === Base.:- ) && length (arg_types_param ) == 2
296
+ if (f === Base.:+ || f === Base.:- ) && length (san_arg_types_param ) == 2
303
297
# we need one array of numbers and one number, in any order
304
- if any (x -> x <: AbstractArray{<:Number} , arg_types_param ) &&
305
- any (x -> x <: Number , arg_types_param )
298
+ if any (x -> x <: AbstractArray{<:Number} , san_arg_types_param ) &&
299
+ any (x -> x <: Number , san_arg_types_param )
306
300
307
301
nounf = f === Base.:+ ? " addition" : " subtraction"
308
302
varnames = (" scalar" , " array" )
309
- first, second = arg_types_param [1 ] <: Number ? varnames : reverse (varnames)
303
+ first, second = san_arg_types_param [1 ] <: Number ? varnames : reverse (varnames)
310
304
fstring = f === Base.:+ ? " +" : " -" # avoid depending on show_default for functions (invalidation)
311
305
print (io, " \n For element-wise $nounf , use broadcasting with dot syntax: $first .$fstring $second " )
312
306
end
@@ -315,17 +309,25 @@ function showerror(io::IO, ex::MethodError)
315
309
print (io, " \n Use square brackets [] for indexing an Array." )
316
310
end
317
311
# Check for local functions that shadow methods in Base
318
- if f_is_function && isdefined (Base, name)
319
- basef = getfield (Base, name)
320
- if basef != = ex. f && hasmethod (basef, arg_types)
321
- print (io, " \n You may have intended to import " )
322
- show_unquoted (io, Expr (:., :Base , QuoteNode (name)))
312
+ let name = ft. name. mt. name
313
+ if f_is_function && isdefined (Base, name)
314
+ basef = getfield (Base, name)
315
+ if basef != = f && hasmethod (basef, arg_types)
316
+ print (io, " \n You may have intended to import " )
317
+ show_unquoted (io, Expr (:., :Base , QuoteNode (name)))
318
+ end
323
319
end
324
320
end
325
- if (ex. world != typemax (UInt) && hasmethod (ex . f, arg_types) &&
326
- ! hasmethod (ex . f, arg_types, world = ex. world))
321
+ if (ex. world != typemax (UInt) && hasmethod (f, arg_types) &&
322
+ ! hasmethod (f, arg_types, world = ex. world))
327
323
curworld = get_world_counter ()
328
324
print (io, " \n The applicable method may be too new: running in world age $(ex. world) , while current world is $(curworld) ." )
325
+ elseif f isa Function
326
+ print (io, " \n The function `$f ` exists, but no method is defined for this combination of argument types." )
327
+ elseif f isa Type
328
+ print (io, " \n The type `$f ` exists, but no method is defined for this combination of argument types when trying to construct it." )
329
+ else
330
+ print (io, " \n The object of type `$(typeof (f)) ` exists, but no method is defined for this combination of argument types when trying to treat it as a callable object." )
329
331
end
330
332
if ! is_arg_types
331
333
# Check for row vectors used where a column vector is intended.
@@ -342,7 +344,7 @@ function showerror(io::IO, ex::MethodError)
342
344
" \n You can convert to a column vector with the vec() function." )
343
345
end
344
346
end
345
- Experimental. show_error_hints (io, ex, arg_types_param , kwargs)
347
+ Experimental. show_error_hints (io, ex, san_arg_types_param , kwargs)
346
348
try
347
349
show_method_candidates (io, ex, kwargs)
348
350
catch ex
@@ -354,16 +356,12 @@ end
354
356
striptype (:: Type{T} ) where {T} = T
355
357
striptype (:: Any ) = nothing
356
358
357
- function showerror_ambiguous (io:: IO , meths, f, args)
359
+ function showerror_ambiguous (io:: IO , meths, f, args:: Type )
360
+ @nospecialize f args
358
361
print (io, " MethodError: " )
359
362
show_signature_function (io, isa (f, Type) ? Type{f} : typeof (f))
360
- print (io, " (" )
361
- p = args. parameters
362
- for (i,a) in enumerate (p)
363
- print (io, " ::" , a)
364
- i < length (p) && print (io, " , " )
365
- end
366
- println (io, " ) is ambiguous.\n\n Candidates:" )
363
+ show_tuple_as_call (io, :var"" , args, hasfirst= false )
364
+ println (io, " is ambiguous.\n\n Candidates:" )
367
365
sigfix = Any
368
366
for m in meths
369
367
print (io, " " )
@@ -375,7 +373,7 @@ function showerror_ambiguous(io::IO, meths, f, args)
375
373
let sigfix= sigfix
376
374
if all (m-> morespecific (sigfix, m. sig), meths)
377
375
print (io, " \n Possible fix, define\n " )
378
- Base . show_tuple_as_call (io, :function , sigfix)
376
+ show_tuple_as_call (io, :function , sigfix)
379
377
else
380
378
print (io, " To resolve the ambiguity, try making one of the methods more specific, or " )
381
379
print (io, " adding a new method more specific than any of the existing applicable methods." )
@@ -401,9 +399,10 @@ stacktrace_contract_userdir()::Bool = Base.get_bool_env("JULIA_STACKTRACE_CONTRA
401
399
stacktrace_linebreaks ():: Bool = Base. get_bool_env (" JULIA_STACKTRACE_LINEBREAKS" , false ) === true
402
400
403
401
function show_method_candidates (io:: IO , ex:: MethodError , @nospecialize kwargs= ())
404
- is_arg_types = isa (ex. args, DataType )
402
+ is_arg_types = ! isa (ex. args, Tuple )
405
403
arg_types = is_arg_types ? ex. args : typesof (ex. args... )
406
- arg_types_param = Any[arg_types. parameters... ]
404
+ arg_types_param = Any[(unwrap_unionall (arg_types):: DataType ). parameters... ]
405
+ arg_types_param = Any[rewrap_unionall (a, arg_types) for a in arg_types_param]
407
406
# Displays the closest candidates of the given function by looping over the
408
407
# functions methods and counting the number of matching arguments.
409
408
f = ex. f
0 commit comments