From b78dc88c378ebd6c0cdbab93e6156b5cf2372af2 Mon Sep 17 00:00:00 2001 From: Bumblebee00 Date: Sun, 9 Feb 2025 13:50:20 +0100 Subject: [PATCH 1/4] Improve error messages for MethodError and add tips for single-method functions (#56325) --- base/errorshow.jl | 12 ++++++++++-- test/errorshow.jl | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index d4b9b3666fbb7..526889427aa29 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -299,13 +299,17 @@ function showerror(io::IO, ex::MethodError) if is_arg_types print(io, "no method matching invoke ") else - print(io, "no method matching ") + print(io, "no method") end buf = IOBuffer() iob = IOContext(buf, io) # for type abbreviation as in #49795; some, like `convert(T, x)`, should not abbreviate show_signature_function(iob, Core.Typeof(f)) + if occursin(r"var\"#\d+#\d+\"", string(ft)) + print(io, " of the anonymous function ", ft) + end show_tuple_as_call(iob, :function, arg_types; hasfirst=false, kwargs = isempty(kwargs) ? nothing : kwargs) - str = String(take!(buf)) + str = String(take!(buf)) # function name + arguments + print(io, " matching ") str = type_limited_string_from_context(io, str) print(io, str) end @@ -373,6 +377,10 @@ function showerror(io::IO, ex::MethodError) catch ex @error "Error showing method candidates, aborted" exception=ex,catch_backtrace() end + # if the function has only on method, print a Tip about the number of arguments to be used + if f isa Function && length(methods(f)) == 1 + print(io, "\n\nTip: the function `$f` was called with ", length(arg_types_param), " arguments, but has only one method accepting ", length(methods(f)[1].sig.parameters)-1, " argument.\n") + end nothing end diff --git a/test/errorshow.jl b/test/errorshow.jl index f83bbe31b7cc4..77c5f5fabd045 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -1259,3 +1259,11 @@ end f33793(x::Float32, y::Float32) = 1 @test_throws "\nClosest candidates are:\n f33793(!Matched::Float32, !Matched::Float32)\n" f33793(Float64(0.0), Float64(0.0)) + +# https://github.com/JuliaLang/julia/issues/56325 +let err_str + f56325 = x->x+1 + err_str = @except_str f56325(1,2) MethodError + @test occursin("MethodError: no method of the anonymous function", err_str) + @test occursin("was called with 2 arguments, but has only one method accepting 1 argument.", err_str) +end From 92b30c2c64089c2fc0cd691a738ace0cfaeba572 Mon Sep 17 00:00:00 2001 From: Bumblebee00 Date: Mon, 10 Feb 2025 13:57:56 +0100 Subject: [PATCH 2/4] splitting in two branches --- base/errorshow.jl | 4 ---- test/errorshow.jl | 1 - 2 files changed, 5 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 526889427aa29..ff993c691193e 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -377,10 +377,6 @@ function showerror(io::IO, ex::MethodError) catch ex @error "Error showing method candidates, aborted" exception=ex,catch_backtrace() end - # if the function has only on method, print a Tip about the number of arguments to be used - if f isa Function && length(methods(f)) == 1 - print(io, "\n\nTip: the function `$f` was called with ", length(arg_types_param), " arguments, but has only one method accepting ", length(methods(f)[1].sig.parameters)-1, " argument.\n") - end nothing end diff --git a/test/errorshow.jl b/test/errorshow.jl index b5893818c3b89..914c0f23210ce 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -1268,5 +1268,4 @@ let err_str f56325 = x->x+1 err_str = @except_str f56325(1,2) MethodError @test occursin("MethodError: no method of the anonymous function", err_str) - @test occursin("was called with 2 arguments, but has only one method accepting 1 argument.", err_str) end From 66f6b7ca5033e99e33d9a6ffd2ca2abedad010cd Mon Sep 17 00:00:00 2001 From: Bumblebee00 Date: Fri, 14 Feb 2025 00:33:40 +0100 Subject: [PATCH 3/4] Implemented review suggestions --- base/errorshow.jl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index ff993c691193e..d8900b78eb897 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -299,17 +299,13 @@ function showerror(io::IO, ex::MethodError) if is_arg_types print(io, "no method matching invoke ") else - print(io, "no method") + print(io, "no method matching ") end buf = IOBuffer() iob = IOContext(buf, io) # for type abbreviation as in #49795; some, like `convert(T, x)`, should not abbreviate show_signature_function(iob, Core.Typeof(f)) - if occursin(r"var\"#\d+#\d+\"", string(ft)) - print(io, " of the anonymous function ", ft) - end show_tuple_as_call(iob, :function, arg_types; hasfirst=false, kwargs = isempty(kwargs) ? nothing : kwargs) - str = String(take!(buf)) # function name + arguments - print(io, " matching ") + str = String(take!(buf)) str = type_limited_string_from_context(io, str) print(io, str) end @@ -350,7 +346,9 @@ function showerror(io::IO, ex::MethodError) curworld = get_world_counter() print(io, "\nThe applicable method may be too new: running in world age $(ex.world), while current world is $(curworld).") elseif f isa Function - print(io, "\nThe function `$f` exists, but no method is defined for this combination of argument types.") + print(io, "\nThe ") + isgensym(nameof(f)) && print(io, "anonymous ") + print(io, "function `$f` exists, but no method is defined for this combination of argument types.") elseif f isa Type print(io, "\nThe type `$f` exists, but no method is defined for this combination of argument types when trying to construct it.") else From f2113bbe13a70e00993c85e2f091d88eaec9700a Mon Sep 17 00:00:00 2001 From: Bumblebee00 Date: Fri, 14 Feb 2025 00:37:38 +0100 Subject: [PATCH 4/4] updated the test of this feature --- test/errorshow.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/errorshow.jl b/test/errorshow.jl index 914c0f23210ce..1b73aa3111f88 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -1267,5 +1267,5 @@ f33793(x::Float32, y::Float32) = 1 let err_str f56325 = x->x+1 err_str = @except_str f56325(1,2) MethodError - @test occursin("MethodError: no method of the anonymous function", err_str) + @test occursin("The anonymous function", err_str) end