From 5c06e930748ef6bdb4ac4751ba16b7b604da3db0 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 29 May 2024 15:47:26 -0700 Subject: [PATCH] merge revision(s) 6ade36c06b7cef948099b8f5f483763498705d12: [Backport #20414] `Fiber#raise` recursively raises on nested resuming_fiber. (#10482) * Improve consistency of `Fiber.current.raise`. --- cont.c | 8 ++++++- spec/ruby/core/fiber/raise_spec.rb | 34 ++++++++++++++++++++++++++++++ version.h | 2 +- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/cont.c b/cont.c index cafcb66091..55040d3d38 100644 --- a/cont.c +++ b/cont.c @@ -3223,7 +3223,13 @@ rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass) static VALUE fiber_raise(rb_fiber_t *fiber, VALUE exception) { - if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) { + if (fiber == fiber_current()) { + rb_exc_raise(exception); + } + else if (fiber->resuming_fiber) { + return fiber_raise(fiber->resuming_fiber, exception); + } + else if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) { return fiber_transfer_kw(fiber, -1, &exception, RB_NO_KEYWORDS); } else { diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb index eb4b39c8be..b3e021e636 100644 --- a/spec/ruby/core/fiber/raise_spec.rb +++ b/spec/ruby/core/fiber/raise_spec.rb @@ -91,6 +91,40 @@ describe "Fiber#raise" do fiber_two.resume.should == [:yield_one, :rescued] end + + ruby_version_is "3.4" do + it "raises on the resumed fiber" do + root_fiber = Fiber.current + f1 = Fiber.new { root_fiber.transfer } + f2 = Fiber.new { f1.resume } + f2.transfer + + -> do + f2.raise(RuntimeError, "Expected error") + end.should raise_error(RuntimeError, "Expected error") + end + + it "raises on itself" do + -> do + Fiber.current.raise(RuntimeError, "Expected error") + end.should raise_error(RuntimeError, "Expected error") + end + + it "should raise on parent fiber" do + f2 = nil + f1 = Fiber.new do + # This is equivalent to Kernel#raise: + f2.raise(RuntimeError, "Expected error") + end + f2 = Fiber.new do + f1.resume + end + + -> do + f2.resume + end.should raise_error(RuntimeError, "Expected error") + end + end end diff --git a/version.h b/version.h index 6cc6423ca6..e6138749cd 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 70 +#define RUBY_PATCHLEVEL 71 #include "ruby/version.h" #include "ruby/internal/abi.h"