From 58fb95af36c86b00b134db5275becf7455ba4790 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 6 Jan 2026 16:13:15 -0600 Subject: [PATCH 1/4] [DOC] Harmonize #== methods (#15805) --- complex.c | 6 +++--- error.c | 4 ++-- hash.c | 14 +++++--------- numeric.c | 4 ++-- object.c | 20 ++++++++++++-------- proc.c | 11 +++++------ range.c | 4 ++-- rational.c | 4 ++-- re.c | 12 ++++++------ string.c | 18 +++++++++--------- struct.c | 4 ++-- 11 files changed, 50 insertions(+), 51 deletions(-) diff --git a/complex.c b/complex.c index a764557990e8dc..7b6c6c2a996a03 100644 --- a/complex.c +++ b/complex.c @@ -1226,10 +1226,10 @@ rb_complex_pow(VALUE self, VALUE other) /* * call-seq: - * complex == object -> true or false + * self == other -> true or false * - * Returns +true+ if self.real == object.real - * and self.imag == object.imag: + * Returns whether both self.real == other.real + * and self.imag == other.imag: * * Complex.rect(2, 3) == Complex.rect(2.0, 3.0) # => true * diff --git a/error.c b/error.c index f21a682d65d352..69dc559c5d03ed 100644 --- a/error.c +++ b/error.c @@ -2159,9 +2159,9 @@ try_convert_to_exception(VALUE obj) /* * call-seq: - * self == object -> true or false + * self == other -> true or false * - * Returns whether +object+ is the same class as +self+ + * Returns whether +other+ is the same class as +self+ * and its #message and #backtrace are equal to those of +self+. * */ diff --git a/hash.c b/hash.c index f264bfba4bc40f..dc47eb6ab77736 100644 --- a/hash.c +++ b/hash.c @@ -3980,17 +3980,13 @@ hash_equal(VALUE hash1, VALUE hash2, int eql) /* * call-seq: - * self == object -> true or false + * self == other -> true or false * - * Returns whether +self+ and +object+ are equal. + * Returns whether all of the following are true: * - * Returns +true+ if all of the following are true: - * - * - +object+ is a +Hash+ object (or can be converted to one). - * - +self+ and +object+ have the same keys (regardless of order). - * - For each key +key+, self[key] == object[key]. - * - * Otherwise, returns +false+. + * - +other+ is a +Hash+ object (or can be converted to one). + * - +self+ and +other+ have the same keys (regardless of order). + * - For each key +key+, self[key] == other[key]. * * Examples: * diff --git a/numeric.c b/numeric.c index 8f866d00bde628..ef44febe1b29cd 100644 --- a/numeric.c +++ b/numeric.c @@ -1501,7 +1501,7 @@ num_equal(VALUE x, VALUE y) * call-seq: * self == other -> true or false * - * Returns +true+ if +other+ has the same value as +self+, +false+ otherwise: + * Returns whether +other+ is numerically equal to +self+: * * 2.0 == 2 # => true * 2.0 == 2.0 # => true @@ -4852,7 +4852,7 @@ fix_equal(VALUE x, VALUE y) * call-seq: * self == other -> true or false * - * Returns +true+ if +self+ is numerically equal to +other+; +false+ otherwise. + * Returns whether +self+ is numerically equal to +other+: * * 1 == 2 #=> false * 1 == 1.0 #=> true diff --git a/object.c b/object.c index ed7e0ff224cf0b..2b3535158fe305 100644 --- a/object.c +++ b/object.c @@ -200,14 +200,18 @@ rb_eql(VALUE obj1, VALUE obj2) /** * call-seq: - * obj == other -> true or false - * obj.equal?(other) -> true or false - * obj.eql?(other) -> true or false - * - * Equality --- At the Object level, #== returns true - * only if +obj+ and +other+ are the same object. Typically, this - * method is overridden in descendant classes to provide - * class-specific meaning. + * self == other -> true or false + * equal?(other) -> true or false + * eql?(other) -> true or false + * + * Returns whether +self+ and +other+ are the same object: + * + * object = Object.new + * object == object # => true + * object == Object.new # => false + * + * Here in class \Object, #==, #equal?, and #eql? are the same method. + * A subclass may override #== to provide class-specific meaning. * * Unlike #==, the #equal? method should never be overridden by * subclasses as it is used to determine object identity (that is, diff --git a/proc.c b/proc.c index 4fa48196caccc2..b3159e14b743d8 100644 --- a/proc.c +++ b/proc.c @@ -1423,10 +1423,10 @@ rb_proc_get_iseq(VALUE self, int *is_proc) } /* call-seq: - * prc == other -> true or false - * prc.eql?(other) -> true or false + * self == other -> true or false + * eql?(other) -> true or false * - * Two procs are the same if, and only if, they were created from the same code block. + * Returns whether +self+ and +other+ were created from the same code block: * * def return_block(&block) * block @@ -1980,10 +1980,9 @@ method_entry_defined_class(const rb_method_entry_t *me) /* * call-seq: - * meth.eql?(other_meth) -> true or false - * meth == other_meth -> true or false + * self == other -> true or false * - * Two method objects are equal if they are bound to the same + * Returns whether +self+ and +other+ are bound to the same * object and refer to the same method definition and the classes * defining the methods are the same class or module. */ diff --git a/range.c b/range.c index c8a4b9938bab8e..fd08a81de7b8b1 100644 --- a/range.c +++ b/range.c @@ -154,14 +154,14 @@ recursive_equal(VALUE range, VALUE obj, int recur) * call-seq: * self == other -> true or false * - * Returns +true+ if and only if: + * Returns whether all of the following are true: * * - +other+ is a range. * - other.begin == self.begin. * - other.end == self.end. * - other.exclude_end? == self.exclude_end?. * - * Otherwise returns +false+. + * Examples: * * r = (1..5) * r == (1..5) # => true diff --git a/rational.c b/rational.c index 5463395459c027..51078f81ad3cf2 100644 --- a/rational.c +++ b/rational.c @@ -1145,9 +1145,9 @@ rb_rational_cmp(VALUE self, VALUE other) /* * call-seq: - * rat == object -> true or false + * self == other -> true or false * - * Returns +true+ if +rat+ equals +object+ numerically. + * Returns whether +self+ and +other+ are numerically equal: * * Rational(2, 3) == Rational(2, 3) #=> true * Rational(5) == 5 #=> true diff --git a/re.c b/re.c index f8672d1d7ce187..fe8e93c6a6b96c 100644 --- a/re.c +++ b/re.c @@ -3544,10 +3544,10 @@ reg_hash(VALUE re) /* * call-seq: - * regexp == object -> true or false + * self == other -> true or false * - * Returns +true+ if +object+ is another \Regexp whose pattern, - * flags, and encoding are the same as +self+, +false+ otherwise: + * Returns whether +other+ is another \Regexp whose pattern, + * flags, and encoding are the same as +self+: * * /foo/ == Regexp.new('foo') # => true * /foo/ == /foo/i # => false @@ -3599,11 +3599,11 @@ match_hash(VALUE match) /* * call-seq: - * matchdata == object -> true or false + * self == other -> true or false * - * Returns +true+ if +object+ is another \MatchData object + * Returns whether +other+ is another \MatchData object * whose target string, regexp, match, and captures - * are the same as +self+, +false+ otherwise. + * are the same as +self+. */ static VALUE diff --git a/string.c b/string.c index 1f2a14f681e6d2..c8233be66fd06a 100644 --- a/string.c +++ b/string.c @@ -4239,11 +4239,11 @@ rb_str_cmp(VALUE str1, VALUE str2) /* * call-seq: - * self == object -> true or false + * self == other -> true or false * - * Returns whether +object+ is equal to +self+. + * Returns whether +other+ is equal to +self+. * - * When +object+ is a string, returns whether +object+ has the same length and content as +self+: + * When +other+ is a string, returns whether +other+ has the same length and content as +self+: * * s = 'foo' * s == 'foo' # => true @@ -4254,11 +4254,11 @@ rb_str_cmp(VALUE str1, VALUE str2) * * "\u{e4 f6 fc}".encode(Encoding::ISO_8859_1) == ("\u{c4 d6 dc}") # => false * - * When +object+ is not a string: + * When +other+ is not a string: * - * - If +object+ responds to method to_str, - * object == self is called and its return value is returned. - * - If +object+ does not respond to to_str, + * - If +other+ responds to method to_str, + * other == self is called and its return value is returned. + * - If +other+ does not respond to to_str, * +false+ is returned. * * Related: {Comparing}[rdoc-ref:String@Comparing]. @@ -12218,9 +12218,9 @@ rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str) /* * call-seq: - * symbol == object -> true or false + * self == other -> true or false * - * Returns +true+ if +object+ is the same object as +self+, +false+ otherwise. + * Returns whether +other+ is the same object as +self+. */ #define sym_equal rb_obj_equal diff --git a/struct.c b/struct.c index a438ddd6136092..145d65f389d6d0 100644 --- a/struct.c +++ b/struct.c @@ -1404,7 +1404,7 @@ recursive_equal(VALUE s, VALUE s2, int recur) * call-seq: * self == other -> true or false * - * Returns +true+ if and only if the following are true; otherwise returns +false+: + * Returns whether both the following are true: * * - other.class == self.class. * - For each member name +name+, other.name == self.name. @@ -1918,7 +1918,7 @@ rb_data_inspect(VALUE s) * call-seq: * self == other -> true or false * - * Returns +true+ if +other+ is the same class as +self+, and all members are + * Returns whether +other+ is the same class as +self+, and all members are * equal. * * Examples: From 5c24f4081d0d163ed91dd20692d09d0c88ac46b1 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 5 Jan 2026 20:25:52 -0500 Subject: [PATCH 2/4] Add potential missing GC guard in iseq_data_to_ary The iseq object might be optimized away by the compiler in iseq_data_to_ary because we mainly only use the iseq_body. With MMTk, this crash occasionally happens: TestIseqLoad#test_stressful_roundtrip [test/-ext-/iseq_load/test_iseq_load.rb:20]: pid 106677 killed by SIGSEGV (signal 11) (core dumped) | -:10: [BUG] Segmentation fault at 0x0000000000f1410c | ruby 4.1.0dev (2026-01-05T23:31:16Z master 5d26a2aeea) +PRISM +GC[mmtk] [x86_64-linux] | | -- Control frame information ----------------------------------------------- | c:0005 p:---- s:0022 e:000021 l:y b:---- CFUNC :to_a | c:0004 p:0039 s:0018 e:000017 l:y b:0001 METHOD -:10 | c:0003 p:0013 s:0010 e:000009 l:y b:0001 METHOD -:16 | c:0002 p:0054 s:0006 e:000005 l:n b:---- EVAL -:26 [FINISH] | c:0001 p:0000 s:0003 E:0003a0 l:y b:---- DUMMY [FINISH] | | -- Ruby level backtrace information ---------------------------------------- | -:26:in '
' | -:16:in 'test_bug8543' | -:10:in 'assert_iseq_roundtrip' | -:10:in 'to_a' | | -- Threading information --------------------------------------------------- | Total ractor count: 1 | Ruby thread count for this ractor: 1 | | -- Machine register context ------------------------------------------------ | RIP: 0x000055b581f866f5 RBP: 0x0000000000000000 RSP: 0x00007ffccce2ffe0 | RAX: 0x00000200ffee2b08 RBX: 0x0000000000f1410c RCX: 0x0000000000000000 | RDX: 0x000000000010c7f2 RDI: 0x00000200ffee2b08 RSI: 0x00000200ffee2b08 | R8: 0x0000000000000004 R9: 0x00000c0803ffb8ac R10: 0x00007fe9074c0cc8 | R11: 0x0000000000000246 R12: 0x0000000000000000 R13: 0x0000000000000001 | R14: 0x0000000000000001 R15: 0x00000200ffee2208 EFL: 0x0000000000010246 | | -- C level backtrace information ------------------------------------------- | ruby(rb_print_backtrace+0x14) [0x55b582119a9f] vm_dump.c:1105 | ruby(rb_vm_bugreport) vm_dump.c:1450 | ruby(rb_bug_for_fatal_signal+0x102) [0x55b582409072] error.c:1131 | ruby(sigsegv+0x46) [0x55b582051bf6] signal.c:948 | /lib/x86_64-linux-gnu/libc.so.6(0x7fe907645330) [0x7fe907645330] | ruby(iseq_data_to_ary+0xe5) [0x55b581f866f5] iseq.c:3380 | ruby(iseq_data_to_ary+0x6b2) [0x55b581f86cc2] iseq.c:3470 | ruby(vm_call_cfunc_with_frame_+0x10d) [0x55b5820e4a0d] vm_insnhelper.c:3902 --- iseq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iseq.c b/iseq.c index 2e13928e920ed0..97047794b1e904 100644 --- a/iseq.c +++ b/iseq.c @@ -3345,6 +3345,7 @@ iseq_type_id(enum rb_iseq_type type) static VALUE iseq_data_to_ary(const rb_iseq_t *iseq) { + VALUE iseq_value = (VALUE)iseq; unsigned int i; long l; const struct rb_iseq_constant_body *const iseq_body = ISEQ_BODY(iseq); @@ -3677,6 +3678,9 @@ iseq_data_to_ary(const rb_iseq_t *iseq) rb_ary_push(val, params); rb_ary_push(val, exception); rb_ary_push(val, body); + + RB_GC_GUARD(iseq_value); + return val; } From b2ed4cdced26f8840e181960c776e950e8bb0396 Mon Sep 17 00:00:00 2001 From: Philip Hallstrom Date: Tue, 6 Jan 2026 14:29:58 -0800 Subject: [PATCH 3/4] [ruby/time] Add changelog URI to time.gemspec https://github.com/ruby/time/commit/08f896ca0d --- lib/time.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/time.gemspec b/lib/time.gemspec index 4b9f9e1218237d..73650ab12e2567 100644 --- a/lib/time.gemspec +++ b/lib/time.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |spec| spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage + spec.metadata["changelog_uri"] = "https://github.com/ruby/time/releases" srcdir, gemspec = File.split(__FILE__) spec.files = Dir.chdir(srcdir) do From a024dca391695d07b24598677ddd6509ae3febfb Mon Sep 17 00:00:00 2001 From: yui-knk Date: Tue, 6 Jan 2026 12:08:48 +0900 Subject: [PATCH 4/4] Remove `in_masgn` field from `struct iseq_compile_data` `in_masgn` has not been used since fb6e3a80009a744a4e0b75660f1ce6da65e20e6c. --- compile.c | 3 --- iseq.h | 1 - 2 files changed, 4 deletions(-) diff --git a/compile.c b/compile.c index bcf22243cfc7af..b7d6b07090ba90 100644 --- a/compile.c +++ b/compile.c @@ -10926,10 +10926,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_MASGN:{ - bool prev_in_masgn = ISEQ_COMPILE_DATA(iseq)->in_masgn; - ISEQ_COMPILE_DATA(iseq)->in_masgn = true; compile_massign(iseq, ret, node, popped); - ISEQ_COMPILE_DATA(iseq)->in_masgn = prev_in_masgn; break; } diff --git a/iseq.h b/iseq.h index fbb8180a496662..5221c8aeb4fdfc 100644 --- a/iseq.h +++ b/iseq.h @@ -129,7 +129,6 @@ struct iseq_compile_data { struct iseq_compile_data_storage *storage_current; } insn; bool in_rescue; - bool in_masgn; int loopval_popped; /* used by NODE_BREAK */ int last_line; int label_no;