From 79aeeda6fa906a07702d0d1c38c59d49d60d3c3c Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 28 Oct 2022 17:15:18 -0400 Subject: [PATCH] hide kwcall methods from the backtrace They are not strictly internal, but also not strictly external, so just assume they should be hidden. Perhaps, in the future, we should figure out a way to signal directly in the line number value that this line can be hidden, so only exactly the inner call gets hidden, but not errors that happen in the kwsorter itself (for example, for computing default values). Then all of these could print comparable backtraces (rather than just hiding the kwcall, as this PR does): ``` julia> f(; a, b) = error() f (generic function with 1 method) julia> f() ERROR: UndefKeywordError: keyword argument `a` not assigned Stacktrace: [1] f() @ Main ./REPL[1]:1 [2] top-level scope @ REPL[2]:1 julia> f(b=1) ERROR: UndefKeywordError: keyword argument `a` not assigned Stacktrace: [1] kwcall(::NamedTuple{(:b,), Tuple{Int64}}, ::typeof(f)) @ Main ./REPL[1]:1 [2] top-level scope @ REPL[3]:1 julia> f(a=1) ERROR: UndefKeywordError: keyword argument `b` not assigned Stacktrace: [1] kwcall(::NamedTuple{(:a,), Tuple{Int64}}, ::typeof(f)) @ Main ./REPL[1]:1 [2] top-level scope @ REPL[4]:1 julia> f(a=1, b=2) ERROR: Stacktrace: [1] error() @ Base ./error.jl:44 [2] f(; a::Int64, b::Int64) @ Main ./REPL[1]:1 [3] kwcall(::NamedTuple{(:a, :b), Tuple{Int64, Int64}}, ::typeof(f)) @ Main ./REPL[1]:1 [4] top-level scope @ REPL[5]:1 ``` Fix #47319 --- base/errorshow.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 16190d64e01e4..636357827a32a 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -850,10 +850,11 @@ function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true) code = lkup.linfo if code isa MethodInstance def = code.def - if def isa Method - if def.name === :kwcall && def.module === Core - continue - end + if def isa Method && def.name !== :kwcall && def.sig <: Tuple{typeof(Core.kwcall),Any,Any,Vararg} + # hide kwcall() methods, which are probably internal keyword sorter methods + # (we print the internal method instead, after demangling + # the argument list, since it has the right line number info) + continue end elseif !lkup.from_c lkup.func === :kwcall && continue