From 40579c3c896522b41e83988d54d102dbec48329a Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Wed, 26 Apr 2023 09:55:27 -0500 Subject: [PATCH] Nospecialize close(c::Channel, excp::Exception) on excp. (#49508) * Nospecialize close(c::Channel, excp::Exception) on excp. Fixes https://github.com/JuliaLang/julia/issues/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. --- base/channels.jl | 3 ++- test/channels.jl | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/base/channels.jl b/base/channels.jl index 0cf3b8d799926..232e73db987f1 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -183,7 +183,8 @@ Close a channel. An exception (optionally given by `excp`), is thrown by: * [`put!`](@ref) on a closed channel. * [`take!`](@ref) and [`fetch`](@ref) on an empty, closed channel. """ -function close(c::Channel, excp::Exception=closed_exception()) +close(c::Channel) = close(c, closed_exception()) # nospecialize on default arg seems to confuse makedocs +function close(c::Channel, @nospecialize(excp::Exception)) lock(c) try c.excp = excp diff --git a/test/channels.jl b/test/channels.jl index 1a989747c3863..9f5f21e835db2 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -619,3 +619,20 @@ end @test n_avail(c) == 0 end end + +# Issue #49507: stackoverflow in type inference caused by close(::Channel, ::Exception) +@testset "close(::Channel, ::StackOverflowError)" begin + ch = let result = Channel() + foo() = try + foo() + catch e; + close(result, e) + end + + foo() # This shouldn't fail with an internal stackoverflow error in inference. + + result + end + + @test (try take!(ch) catch e; e; end) isa StackOverflowError +end