Skip to content

Commit a152d11

Browse files
authored
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 3f7ae8b commit a152d11

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

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
@@ -626,3 +626,20 @@ end
626626
@test n_avail(c) == 0
627627
end
628628
end
629+
630+
# Issue #49507: stackoverflow in type inference caused by close(::Channel, ::Exception)
631+
@testset "close(::Channel, ::StackOverflowError)" begin
632+
ch = let result = Channel()
633+
foo() = try
634+
foo()
635+
catch e;
636+
close(result, e)
637+
end
638+
639+
foo() # This shouldn't fail with an internal stackoverflow error in inference.
640+
641+
result
642+
end
643+
644+
@test (try take!(ch) catch e; e; end) isa StackOverflowError
645+
end

0 commit comments

Comments
 (0)