Skip to content

Commit 2879527

Browse files
committed
Nospecialize close(c::Channel, excp::Exception) on excp. (#49508)
* Nospecialize close(c::Channel, excp::Exception) on excp. Fixes #49507. Avoids dynamic dispatch when closing a Channel with an Exception, and should avoid a call into the runtime for julia compilation when attempting to report an exception. * Add test for this case.
1 parent a49a909 commit 2879527

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

base/channels.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ Close a channel. An exception (optionally given by `excp`), is thrown by:
183183
* [`put!`](@ref) on a closed channel.
184184
* [`take!`](@ref) and [`fetch`](@ref) on an empty, closed channel.
185185
"""
186-
function close(c::Channel, excp::Exception=closed_exception())
186+
close(c::Channel) = close(c, closed_exception()) # nospecialize on default arg seems to confuse makedocs
187+
function close(c::Channel, @nospecialize(excp::Exception))
187188
lock(c)
188189
try
189190
c.excp = excp

test/channels.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,20 @@ end
619619
@test n_avail(c) == 0
620620
end
621621
end
622+
623+
# Issue #49507: stackoverflow in type inference caused by close(::Channel, ::Exception)
624+
@testset "close(::Channel, ::StackOverflowError)" begin
625+
ch = let result = Channel()
626+
foo() = try
627+
foo()
628+
catch e;
629+
close(result, e)
630+
end
631+
632+
foo() # This shouldn't fail with an internal stackoverflow error in inference.
633+
634+
result
635+
end
636+
637+
@test (try take!(ch) catch e; e; end) isa StackOverflowError
638+
end

0 commit comments

Comments
 (0)