summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2022-09-28 18:54:05 +0200
committerBenoit Daloze <eregontp@gmail.com>2022-09-29 15:48:35 +0200
commit94cea3e4d0a60326bd95be762819eed8ccd59ca6 (patch)
tree3f1ce9e04741e68ab53728e8ced70fa05e759d40 /proc.c
parent892f350a7db4d2cc99c5061d2e74498dfc4809ca (diff)
downloadruby-94cea3e4d0a60326bd95be762819eed8ccd59ca6.tar.gz
Fix {Method,UnboundMethod}#super_method for zsuper methods
* We need to resolve the zsuper method first, and then look the super method of that.
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/proc.c b/proc.c
index 50db2daa46..8e79007d5c 100644
--- a/proc.c
+++ b/proc.c
@@ -3363,24 +3363,25 @@ method_super_method(VALUE method)
const struct METHOD *data;
VALUE super_class, iclass;
ID mid;
- const rb_method_entry_t *me;
+ const rb_method_entry_t *super_me, *me;
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
- iclass = data->iclass;
- if (!iclass) return Qnil;
- if (data->me->def->type == VM_METHOD_TYPE_ALIAS && data->me->defined_class) {
- super_class = RCLASS_SUPER(rb_find_defined_class_by_owner(data->me->defined_class,
- data->me->def->body.alias.original_me->owner));
- mid = data->me->def->body.alias.original_me->def->original_id;
+ me = zsuper_resolve(data->me);
+ VALUE defined_class = me->defined_class ? me->defined_class : me->owner;
+ if (!defined_class) return Qnil;
+ if (me->def->type == VM_METHOD_TYPE_ALIAS && me->defined_class) {
+ super_class = RCLASS_SUPER(rb_find_defined_class_by_owner(me->defined_class,
+ me->def->body.alias.original_me->owner));
+ mid = me->def->body.alias.original_me->def->original_id;
}
else {
- super_class = RCLASS_SUPER(RCLASS_ORIGIN(iclass));
- mid = data->me->def->original_id;
+ super_class = RCLASS_SUPER(RCLASS_ORIGIN(defined_class));
+ mid = me->def->original_id;
}
if (!super_class) return Qnil;
- me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(super_class, mid, &iclass);
- if (!me) return Qnil;
- return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE);
+ super_me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(super_class, mid, &iclass);
+ if (!super_me) return Qnil;
+ return mnew_internal(super_me, super_me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE);
}
/*