diff options
author | Benoit Daloze <[email protected]> | 2022-08-15 16:01:33 +0200 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2022-08-20 13:44:00 +0200 |
commit | 209631a45f9682dedf718f4b4a140efe7d21a6fc () | |
tree | 4fe16e820f45b927f6d5b11637d9dff79ab53e4a | |
parent | 8212aab81a77a2a91fb7c1681b4968171193b48f (diff) |
Consider resolved-through-zsuper methods equal for compatibility
* Fixes https://bugs.ruby-lang.org/issues/18751
Notes: Merged: https://.com/ruby/ruby/pull/6242
-rw-r--r-- | proc.c | 65 | ||||
-rw-r--r-- | spec/ruby/core/unboundmethod/equal_value_spec.rb | 37 | ||||
-rw-r--r-- | test/ruby/test_method.rb | 18 |
3 files changed, 86 insertions, 34 deletions
@@ -1738,6 +1738,27 @@ mnew_unbound(VALUE klass, ID id, VALUE mclass, int scope) return mnew_from_me(me, klass, iclass, Qundef, id, mclass, scope); } static inline VALUE method_entry_defined_class(const rb_method_entry_t *me) { @@ -1798,10 +1819,13 @@ method_eq(VALUE method, VALUE other) m1 = (struct METHOD *)DATA_PTR(method); m2 = (struct METHOD *)DATA_PTR(other); - klass1 = method_entry_defined_class(m1->me); - klass2 = method_entry_defined_class(m2->me); - if (!rb_method_entry_eq(m1->me, m2->me) || klass1 != klass2 || m1->klass != m2->klass || m1->recv != m2->recv) { @@ -2945,22 +2969,12 @@ rb_method_entry_location(const rb_method_entry_t *me) return method_def_location(me->def); } -static VALUE method_super_method(VALUE method); - static const rb_method_definition_t * zsuper_ref_method_def(VALUE method) { - const rb_method_definition_t *def = rb_method_def(method); - VALUE super_method; - while (def->type == VM_METHOD_TYPE_ZSUPER) { - super_method = method_super_method(method); - if (NIL_P(super_method)) { - break; - } - method = super_method; - def = rb_method_def(method); - } - return def; } /* @@ -3124,25 +3138,8 @@ method_inspect(VALUE method) if (data->me->def->type == VM_METHOD_TYPE_ALIAS) { defined_class = data->me->def->body.alias.original_me->owner; } - else if (data->me->def->type == VM_METHOD_TYPE_ZSUPER) { - const rb_method_definition_t *zsuper_ref_def = data->me->def; - struct METHOD *zsuper_ref_data; - VALUE super_method; - - do { - super_method = method_super_method(method); - if (NIL_P(super_method)) { - break; - } - method = super_method; - zsuper_ref_def = rb_method_def(method); - } while (zsuper_ref_def->type == VM_METHOD_TYPE_ZSUPER); - - TypedData_Get_Struct(method, struct METHOD, &method_data_type, zsuper_ref_data); - defined_class = method_entry_defined_class(zsuper_ref_data->me); - } else { - defined_class = method_entry_defined_class(data->me); } if (RB_TYPE_P(defined_class, T_ICLASS)) { @@ -98,4 +98,41 @@ describe "UnboundMethod#==" do (@discard_1 == UnboundMethodSpecs::Methods.instance_method(:discard_1)).should == false end end @@ -1241,6 +1241,24 @@ class TestMethod < Test::Unit::TestCase assert_raise_with_message(NoMethodError, /super: no superclass method `foo'/) { unbound.bind_call(obj) } end def rest_parameter(*rest) rest end |