Skip to content

Commit d1f901b

Browse files
NHDalykpamnany
authored andcommitted
Nospecialize close(c::Channel, excp::Exception) on excp. (JuliaLang#49508)
* Nospecialize close(c::Channel, excp::Exception) on excp. Fixes JuliaLang#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 1c2bfe5 commit d1f901b

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

0 commit comments

Comments
 (0)