Skip to content

Commit e6bee4f

Browse files
committed
[GR-19220] Fix super method lookup for unbounded added methods
PullRequest: truffleruby/3893
2 parents 0e633b8 + c3c330f commit e6bee4f

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Bug fixes:
88
* Fix `Dir.glob` returning blank string entry with leading `**/` in glob and `base:` argument (@rwstauner).
99
* Fix class lookup after an object's class has been replaced by `IO#reopen` (@itarato, @eregon).
1010
* Fix `Marshal.load` and raise `ArgumentError` when dump is broken and is too short (#3108, @andrykonchin).
11+
* Fix `super` method lookup for unbounded attached methods (#3131, @itarato).
1112

1213
Compatibility:
1314

spec/ruby/core/module/define_method_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ class << klass
133133
klass.should have_public_instance_method(:baz)
134134
end
135135
end
136+
137+
it "sets the method owner for a dynamically added method with a different original owner" do
138+
mixin_module = Module.new do
139+
def bar; end
140+
end
141+
142+
foo = Object.new
143+
foo.singleton_class.define_method(:bar, mixin_module.instance_method(:bar))
144+
145+
foo.method(:bar).owner.should == foo.singleton_class
146+
end
136147
end
137148

138149
describe "passed a block" do

spec/ruby/language/super_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,25 @@ def a(arg)
203203
-> { klass.new.a(:a_called) }.should raise_error(RuntimeError)
204204
end
205205

206+
it "is able to navigate to super, when a method is defined dynamically on the singleton class" do
207+
foo_class = Class.new do
208+
def bar
209+
"bar"
210+
end
211+
end
212+
213+
mixin_module = Module.new do
214+
def bar
215+
"super_" + super
216+
end
217+
end
218+
219+
foo = foo_class.new
220+
foo.singleton_class.define_method(:bar, mixin_module.instance_method(:bar))
221+
222+
foo.bar.should == "super_bar"
223+
end
224+
206225
# Rubinius ticket github#157
207226
it "calls method_missing when a superclass method is not found" do
208227
SuperSpecs::MM_B.new.is_a?(Hash).should == false

src/main/java/org/truffleruby/core/module/ModuleNodes.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,8 @@ private RubySymbol addInternalMethod(RubyModule module, String name, InternalMet
15051505

15061506
final Visibility visibility = DeclarationContext
15071507
.findVisibilityCheckSelfAndDefaultDefinee(module, callerFrame);
1508-
module.addMethodConsiderNameVisibility(getContext(), method, visibility, this);
1508+
module.addMethodConsiderNameVisibility(getContext(), method.withOwner(module).withDeclaringModule(module),
1509+
visibility, this);
15091510
return getSymbol(method.getName());
15101511
}
15111512

0 commit comments

Comments
 (0)