Skip to content

Commit 24f34d8

Browse files
timholyIanButterworth
authored andcommitted
Limit type-printing in MethodError (#50809)
This applies the same `...` depth-based parametric truncation to the signature in `MethodError` that we use in printing stacktraces. Fixes #50803 (cherry picked from commit 90b4eed)
1 parent 19fdcce commit 24f34d8

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

base/client.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ scrub_repl_backtrace(stack::ExceptionStack) =
103103
ExceptionStack(Any[(;x.exception, backtrace = scrub_repl_backtrace(x.backtrace)) for x in stack])
104104

105105
istrivialerror(stack::ExceptionStack) =
106-
length(stack) == 1 && length(stack[1].backtrace) 1
107-
# frame 1 = top level; assumes already went through scrub_repl_backtrace
106+
length(stack) == 1 && length(stack[1].backtrace) 1 && !isa(stack[1].exception, MethodError)
107+
# frame 1 = top level; assumes already went through scrub_repl_backtrace; MethodError see #50803
108108

109109
function display_error(io::IO, stack::ExceptionStack)
110110
printstyled(io, "ERROR: "; bold=true, color=Base.error_color())

base/errorshow.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,20 +268,24 @@ function showerror(io::IO, ex::MethodError)
268268
f_is_function = true
269269
end
270270
print(io, "no method matching ")
271-
show_signature_function(io, isa(f, Type) ? Type{f} : typeof(f))
272-
print(io, "(")
271+
iob = IOContext(IOBuffer(), io) # for type abbreviation as in #49795; some, like `convert(T, x)`, should not abbreviate
272+
show_signature_function(iob, isa(f, Type) ? Type{f} : typeof(f))
273+
print(iob, "(")
273274
for (i, typ) in enumerate(arg_types_param)
274-
print(io, "::", typ)
275-
i == length(arg_types_param) || print(io, ", ")
275+
print(iob, "::", typ)
276+
i == length(arg_types_param) || print(iob, ", ")
276277
end
277278
if !isempty(kwargs)
278-
print(io, "; ")
279+
print(iob, "; ")
279280
for (i, (k, v)) in enumerate(kwargs)
280-
print(io, k, "::", typeof(v))
281-
i == length(kwargs)::Int || print(io, ", ")
281+
print(iob, k, "::", typeof(v))
282+
i == length(kwargs)::Int || print(iob, ", ")
282283
end
283284
end
284-
print(io, ")")
285+
print(iob, ")")
286+
str = String(take!(unwrapcontext(iob)[1]))
287+
str = type_limited_string_from_context(io, str)
288+
print(io, str)
285289
end
286290
# catch the two common cases of element-wise addition and subtraction
287291
if (f === Base.:+ || f === Base.:-) && length(arg_types_param) == 2

base/show.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,17 +2557,22 @@ function show_tuple_as_call(out::IO, name::Symbol, sig::Type;
25572557
print_within_stacktrace(io, ")", bold=true)
25582558
show_method_params(io, tv)
25592559
str = String(take!(unwrapcontext(io)[1]))
2560+
str = type_limited_string_from_context(out, str)
2561+
print(out, str)
2562+
nothing
2563+
end
2564+
2565+
function type_limited_string_from_context(out::IO, str::String)
25602566
typelimitflag = get(out, :stacktrace_types_limited, nothing)
25612567
if typelimitflag isa RefValue{Bool}
2562-
sz = get(out, :displaysize, (typemax(Int), typemax(Int)))::Tuple{Int, Int}
2568+
sz = get(out, :displaysize, displaysize(out))::Tuple{Int, Int}
25632569
str_lim = type_depth_limit(str, max(sz[2], 120))
25642570
if sizeof(str_lim) < sizeof(str)
25652571
typelimitflag[] = true
25662572
end
25672573
str = str_lim
25682574
end
2569-
print(out, str)
2570-
nothing
2575+
return str
25712576
end
25722577

25732578
# limit nesting depth of `{ }` until string textwidth is less than `n`

test/errorshow.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,25 @@ foo_9965(x::Int) = 2x
549549
@test occursin("got unsupported keyword argument \"w\"", String(take!(io)))
550550
end
551551

552+
@testset "MethodError with long types (#50803)" begin
553+
a = view(reinterpret(reshape, UInt8, PermutedDimsArray(rand(5, 7), (2, 1))), 2:3, 2:4, 1:4) # a mildly-complex type
554+
function f50803 end
555+
ex50803 = try
556+
f50803(a, a, a, a, a, a)
557+
catch e
558+
e
559+
end::MethodError
560+
tlf = Ref(false)
561+
str = sprint(Base.showerror, ex50803; context=(:displaysize=>(1000, 120), :stacktrace_types_limited=>tlf))
562+
@test tlf[]
563+
@test occursin("::SubArray{…}", str)
564+
tlf[] = false
565+
str = sprint(Base.showerror, ex50803; context=(:displaysize=>(1000, 10000), :stacktrace_types_limited=>tlf))
566+
@test !tlf[]
567+
str = sprint(Base.showerror, ex50803; context=(:displaysize=>(1000, 120)))
568+
@test !occursin("::SubArray{…}", str)
569+
end
570+
552571
# Issue #20556
553572
import REPL
554573
module EnclosingModule

0 commit comments

Comments
 (0)