From 1ee4b43a56e9539d3b09c08114c59cb49857b956 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 13 May 2025 21:39:48 +0200 Subject: [PATCH] Set#merge: raise if called during iteration [Bug #21332] --- set.c | 5 +++++ spec/ruby/core/set/merge_spec.rb | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/set.c b/set.c index b08b295753..8676c62cd3 100644 --- a/set.c +++ b/set.c @@ -1139,6 +1139,11 @@ set_i_merge(int argc, VALUE *argv, VALUE set) if (rb_keyword_given_p()) { rb_raise(rb_eArgError, "no keywords accepted"); } + + if (set_iterating_p(set)) { + rb_raise(rb_eRuntimeError, "cannot add to set during iteration"); + } + rb_check_frozen(set); int i; diff --git a/spec/ruby/core/set/merge_spec.rb b/spec/ruby/core/set/merge_spec.rb index 2ee6a4b709..0c6ed27670 100644 --- a/spec/ruby/core/set/merge_spec.rb +++ b/spec/ruby/core/set/merge_spec.rb @@ -16,6 +16,13 @@ describe "Set#merge" do -> { Set[1, 2].merge(Object.new) }.should raise_error(ArgumentError) end + it "raises RuntimeError when called during iteration" do + set = Set[:a, :b] + set.each do |_m| + -> { set.merge([1, 2]) }.should raise_error(RuntimeError, /iteration/) + end + end + ruby_version_is ""..."3.3" do it "accepts only a single argument" do -> { Set[].merge([], []) }.should raise_error(ArgumentError, "wrong number of arguments (given 2, expected 1)")