summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <[email protected]>2020-02-09 20:13:49 +0900
committerNobuyoshi Nakada <[email protected]>2020-02-09 20:13:49 +0900
commite3e96e3faa1683c8ee832cb6da6f9f96d18b0d77 (patch)
treeaca0cf7dafdd2527a04d366d0250d5ee1c1ed2a4
parent0f05b234fba2d961f1740c094a83f9831c15b210 (diff)
Check if bindable against the refined target [Bug #16617]
-rw-r--r--common.mk1
-rw-r--r--proc.c5
-rw-r--r--test/ruby/test_refinement.rb19
3 files changed, 25 insertions, 0 deletions
diff --git a/common.mk b/common.mk
index 59d11a968c..617d39941a 100644
--- a/common.mk
+++ b/common.mk
@@ -3224,6 +3224,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/array.h
proc.$(OBJEXT): $(top_srcdir)/internal/class.h
proc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
proc.$(OBJEXT): $(top_srcdir)/internal/error.h
+proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
proc.$(OBJEXT): $(top_srcdir)/internal/object.h
diff --git a/proc.c b/proc.c
index 47f4e668b5..83ec61d0f5 100644
--- a/proc.c
+++ b/proc.c
@@ -14,6 +14,7 @@
#include "internal.h"
#include "internal/class.h"
#include "internal/error.h"
+#include "internal/eval.h"
#include "internal/object.h"
#include "internal/proc.h"
#include "internal/symbol.h"
@@ -2366,6 +2367,10 @@ convert_umethod_to_method_components(VALUE method, VALUE recv, VALUE *methclass_
VALUE iclass = data->me->defined_class;
VALUE klass = CLASS_OF(recv);
+ if (RB_TYPE_P(methclass, T_MODULE)) {
+ VALUE refined_class = rb_refinement_module_get_refined_class(methclass);
+ if (!NIL_P(refined_class)) methclass = refined_class;
+ }
if (!RB_TYPE_P(methclass, T_MODULE) &&
methclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, methclass)) {
if (FL_TEST(methclass, FL_SINGLETON)) {
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index c6707ff54c..1f2a67eeb2 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -2386,6 +2386,25 @@ class TestRefinement < Test::Unit::TestCase
assert_equal(0, Bug13446::GenericEnumerable.new.sum)
end
+ def test_unbound_refine_method
+ a = EnvUtil.labeled_class("A") do
+ def foo
+ self.class
+ end
+ end
+ b = EnvUtil.labeled_class("B")
+ bar = EnvUtil.labeled_module("R") do
+ break refine a do
+ def foo
+ super
+ end
+ end
+ end
+ assert_raise(TypeError) do
+ bar.instance_method(:foo).bind(b.new)
+ end
+ end
+
private
def eval_using(mod, s)