Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show: Fix non-stacktrace show of toplevel MethodInstance #54338

Merged
merged 1 commit into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
show: Fix non-stacktrace show of toplevel MethodInstance
While we're here, also check before accessing the `uninferred` field.
Top-level MethodInstances should always have this, but the system
doesn't enforce this and it's rude for a `show` method to throw on
corrupted data (since that's what people use to debug that).
  • Loading branch information
Keno committed May 2, 2024
commit b17224deaa885e2ca3b512a88b458ffbfab66584
20 changes: 11 additions & 9 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1336,15 +1336,15 @@ end

show(io::IO, l::Core.MethodInstance) = show_mi(io, l)

function show_mi(io::IO, l::Core.MethodInstance, from_stackframe::Bool=false)
def = l.def
function show_mi(io::IO, mi::Core.MethodInstance, from_stackframe::Bool=false)
def = mi.def
if isa(def, Method)
if isdefined(def, :generator) && l === def.generator
if isdefined(def, :generator) && mi === def.generator
print(io, "MethodInstance generator for ")
show(io, def)
else
print(io, "MethodInstance for ")
show_tuple_as_call(io, def.name, l.specTypes; qualified=true)
show_tuple_as_call(io, def.name, mi.specTypes; qualified=true)
end
else
print(io, "Toplevel MethodInstance thunk")
Expand All @@ -1353,11 +1353,13 @@ function show_mi(io::IO, l::Core.MethodInstance, from_stackframe::Bool=false)
# added by other means. But if it isn't, then we should try
# to print a little more identifying information.
if !from_stackframe
di = mi.uninferred.debuginfo
file, line = IRShow.debuginfo_firstline(di)
file = string(file)
line = isempty(file) || line < 0 ? "<unknown>" : "$file:$line"
print(io, " from ", def, " starting at ", line)
if isdefined(mi, :uninferred)
di = mi.uninferred.debuginfo
file, line = IRShow.debuginfo_firstline(di)
file = string(file)
line = isempty(file) || line < 0 ? "<unknown>" : "$file:$line"
print(io, " from ", def, " starting at ", line)
end
end
end
end
Expand Down
7 changes: 7 additions & 0 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2694,3 +2694,10 @@ let lowered = Meta.lower(Main, Expr(:let, Expr(:block), Expr(:block, Expr(:tople
# Check that this gets printed as `_1 = 1` not `y = 1`
@test contains(sprint(show, ci), "_1 = 1")
end

# Toplevel MethodInstance with undef :uninferred
let topmi = ccall(:jl_new_method_instance_uninit, Ref{Core.MethodInstance}, ());
topmi.specTypes = Tuple{}
topmi.def = Main
@test contains(repr(topmi), "Toplevel MethodInstance")
end