Properly resolve refinements in defined? on method call [Bug #16932]

This commit is contained in:
Nobuyoshi Nakada 2020-06-03 23:05:55 +09:00
Родитель 3ced77a82a
Коммит 8340c773e5
3 изменённых файлов: 30 добавлений и 2 удалений

Просмотреть файл

@ -301,4 +301,32 @@ class TestDefined < Test::Unit::TestCase
def test_top_level_constant_not_defined
assert_nil(defined?(TestDefined::Object))
end
class RefinedClass
end
module RefiningModule
refine RefinedClass do
def pub
end
end
def self.call_without_using(x = RefinedClass.new)
defined?(x.pub)
end
using self
def self.call_with_using(x = RefinedClass.new)
defined?(x.pub)
end
end
def test_defined_refined_call_without_using
assert(!RefiningModule.call_without_using, "refined public method without using")
end
def test_defined_refined_call_with_using
assert(RefiningModule.call_with_using, "refined public method with using")
end
end

Просмотреть файл

@ -3660,7 +3660,7 @@ vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_
break;
case DEFINED_METHOD:{
VALUE klass = CLASS_OF(v);
const rb_method_entry_t *me = rb_method_entry(klass, SYM2ID(obj));
const rb_method_entry_t *me = rb_method_entry_with_refinements(klass, SYM2ID(obj), NULL);
if (me) {
switch (METHOD_ENTRY_VISI(me)) {

Просмотреть файл

@ -1088,7 +1088,7 @@ method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *
return me;
}
const rb_method_entry_t *
MJIT_FUNC_EXPORTED const rb_method_entry_t *
rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
{
return method_entry_resolve_refinement(klass, id, TRUE, defined_class_ptr);