Skip to content

Commit 867d80d

Browse files
authored
Use unwrapva in MethodError candidates (#42161)
I found an example of a method declaration with an argument typed as `a::Vararg`, and this triggered an error in showing method candidates. It's always bad when there's an error triggered when handling an error. This PR makes the code more robust against such problems. It's worth noting that this type of method declaration shouldn't be used: it is better as `a...`. The only time you should explicitly use `Vararg` is when you are specifying both `T` and `N` in `Vararg{T,N}`.
1 parent 3a775cf commit 867d80d

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

base/errorshow.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=()
419419
# If isvarargtype then it checks whether the rest of the input arguments matches
420420
# the varargtype
421421
if Base.isvarargtype(sig[i])
422-
sigstr = (unwrap_unionall(sig[i]).T, "...")
422+
sigstr = (unwrapva(unwrap_unionall(sig[i])), "...")
423423
j = length(t_i)
424424
else
425425
sigstr = (sig[i],)
@@ -456,7 +456,7 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=()
456456
# It ensures that methods like f(a::AbstractString...) gets the correct
457457
# number of right_matches
458458
for t in arg_types_param[length(sig):end]
459-
if t <: rewrap_unionall(unwrap_unionall(sig[end]).T, method.sig)
459+
if t <: rewrap_unionall(unwrapva(unwrap_unionall(sig[end])), method.sig)
460460
right_matches += 1
461461
end
462462
end
@@ -469,7 +469,7 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=()
469469
for (k, sigtype) in enumerate(sig[length(t_i)+1:end])
470470
sigtype = isvarargtype(sigtype) ? unwrap_unionall(sigtype) : sigtype
471471
if Base.isvarargtype(sigtype)
472-
sigstr = ((sigtype::Core.TypeofVararg).T, "...")
472+
sigstr = (unwrapva(sigtype::Core.TypeofVararg), "...")
473473
else
474474
sigstr = (sigtype,)
475475
end

test/errorshow.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ addConstraint_15639(c::Int64; uncset=nothing) = addConstraint_15639(Int32(c), un
184184
Base.show_method_candidates(buf, MethodError(addConstraint_15639, (Int32(1),)), pairs((uncset = nothing,)))
185185
@test String(take!(buf)) == "\nClosest candidates are:\n addConstraint_15639(::Int32)$cfile$(ac15639line + 1) got unsupported keyword argument \"uncset\"\n addConstraint_15639(!Matched::Int64; uncset)$cfile$(ac15639line + 2)"
186186

187+
# Busted Vararg method definitions
188+
bad_vararg_decl(x::Int, y::Vararg) = 1 # don't do this, instead use (x::Int, y...)
189+
Base.show_method_candidates(buf, try bad_vararg_decl("hello", 3) catch e e end)
190+
@test occursin("bad_vararg_decl(!Matched::$Int, ::Any...)", String(take!(buf)))
191+
187192
macro except_str(expr, err_type)
188193
return quote
189194
let err = nothing

0 commit comments

Comments
 (0)