Skip to content

Commit 703b3f8

Browse files
authored
hide internally created methods in stacktraces that occur as a result of argument forwarding (#49102)
1 parent 489d076 commit 703b3f8

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

base/errorshow.jl

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,73 @@ function _simplify_include_frames(trace)
823823
return trace[kept_frames]
824824
end
825825

826+
# Collapse frames that have the same location (in some cases)
827+
function _collapse_repeated_frames(trace)
828+
kept_frames = trues(length(trace))
829+
last_frame = nothing
830+
for i in 1:length(trace)
831+
frame::StackFrame, _ = trace[i]
832+
if last_frame !== nothing && frame.file == last_frame.file && frame.line == last_frame.line
833+
#=
834+
Handles this case:
835+
836+
f(g, a; kw...) = error();
837+
@inline f(a; kw...) = f(identity, a; kw...);
838+
f(1)
839+
840+
which otherwise ends up as:
841+
842+
[4] #f#4 <-- useless
843+
@ ./REPL[2]:1 [inlined]
844+
[5] f(a::Int64)
845+
@ Main ./REPL[2]:1
846+
=#
847+
if startswith(sprint(show, last_frame), "#")
848+
kept_frames[i-1] = false
849+
end
850+
851+
#= Handles this case
852+
g(x, y=1, z=2) = error();
853+
g(1)
854+
855+
which otherwise ends up as:
856+
857+
[2] g(x::Int64, y::Int64, z::Int64)
858+
@ Main ./REPL[1]:1
859+
[3] g(x::Int64) <-- useless
860+
@ Main ./REPL[1]:1
861+
=#
862+
if frame.linfo isa MethodInstance && last_frame.linfo isa MethodInstance &&
863+
frame.linfo.def isa Method && last_frame.linfo.def isa Method
864+
m, last_m = frame.linfo.def::Method, last_frame.linfo.def::Method
865+
params, last_params = Base.unwrap_unionall(m.sig).parameters, Base.unwrap_unionall(last_m.sig).parameters
866+
867+
if last_m.nkw != 0
868+
pos_sig_params = Base.rewrap_unionall(Tuple{last_params[(last_m.nkw+2):end]...}, last_m.sig).parameters
869+
issame = true
870+
if pos_sig_params == params
871+
kept_frames[i] = false
872+
end
873+
end
874+
if length(last_params) > length(params)
875+
issame = true
876+
for i = 1:length(params)
877+
issame &= params[i] == last_params[i]
878+
end
879+
if issame
880+
kept_frames[i] = false
881+
end
882+
end
883+
end
884+
885+
# TODO: Detect more cases that can be collapsed
886+
end
887+
last_frame = frame
888+
end
889+
return trace[kept_frames]
890+
end
891+
892+
826893
function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true)
827894
n = 0
828895
last_frame = StackTraces.UNKNOWN
@@ -875,7 +942,9 @@ function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true)
875942
if n > 0
876943
push!(ret, (last_frame, n))
877944
end
878-
return _simplify_include_frames(ret)
945+
trace = _simplify_include_frames(ret)
946+
trace = _collapse_repeated_frames(trace)
947+
return trace
879948
end
880949

881950
function show_exception_stack(io::IO, stack)

test/errorshow.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,3 +947,43 @@ let buf = IOBuffer()
947947
Base.show_method_candidates(buf, Base.MethodError(isa, ()), pairs((a = 5,)))
948948
@test isempty(take!(buf))
949949
end
950+
951+
f_internal_wrap(g, a; kw...) = error();
952+
@inline f_internal_wrap(a; kw...) = f_internal_wrap(identity, a; kw...);
953+
bt = try
954+
f_internal_wrap(1)
955+
catch
956+
catch_backtrace()
957+
end
958+
@test !occursin("#f_internal_wrap#", sprint(Base.show_backtrace, bt))
959+
960+
g_collapse_pos(x, y=1.0, z=2.0) = error()
961+
bt = try
962+
g_collapse_pos(1.0)
963+
catch
964+
catch_backtrace()
965+
end
966+
bt_str = sprint(Base.show_backtrace, bt)
967+
@test occursin("g_collapse_pos(x::Float64, y::Float64, z::Float64)", bt_str)
968+
@test !occursin("g_collapse_pos(x::Float64)", bt_str)
969+
970+
g_collapse_kw(x; y=2.0) = error()
971+
bt = try
972+
g_collapse_kw(1.0)
973+
catch
974+
catch_backtrace()
975+
end
976+
bt_str = sprint(Base.show_backtrace, bt)
977+
@test occursin("g_collapse_kw(x::Float64; y::Float64)", bt_str)
978+
@test !occursin("g_collapse_kw(x::Float64)", bt_str)
979+
980+
g_collapse_pos_kw(x, y=1.0; z=2.0) = error()
981+
bt = try
982+
g_collapse_pos_kw(1.0)
983+
catch
984+
catch_backtrace()
985+
end
986+
bt_str = sprint(Base.show_backtrace, bt)
987+
@test occursin("g_collapse_pos_kw(x::Float64, y::Float64; z::Float64)", bt_str)
988+
@test !occursin("g_collapse_pos_kw(x::Float64, y::Float64)", bt_str)
989+
@test !occursin("g_collapse_pos_kw(x::Float64)", bt_str)

0 commit comments

Comments
 (0)