Bug #21535
closed`NoMethodError` becomes `NameError`when using `...` delegation and method call indirection
Description
Consider this code:
class Test
def foo(...)
nil.foo(...)
end
def foo_indirect
foo
end
end
begin
Test.new.foo
rescue => e
puts e.class
end
begin
Test.new.foo_indirect
rescue => e
puts e.class
end
$ ruby -v foo.rb
ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [x86_64-linux]
NoMethodError
NoMethodError
$ ruby -v foo.rb
ruby 3.5.0dev (2025-08-08T02:57:23Z master 3ad26d0501) +PRISM [x86_64-linux]
NoMethodError
NameError
On ruby 3.3 it used to always raise a NoMethodError
. Starting with Ruby 3.4, it raises a NoMethodError
when calling the method directly, and a NameError
when the method is called indirectly via a different method.
The context is the delegate
method from rails (original issue https://github.com/rails/rails/issues/55463), which rescues the NoMethodError
to raise a more specific error class.
The problem is the ...
delegation. If the method accepts no arguments, *, **
, or something else, it behaves as expected.
Updated by Earlopain (Earlopain _) about 1 month ago
Maybe https://bugs.ruby-lang.org/issues/21196 is of relevance
Updated by byroot (Jean Boussier) 28 days ago
- Backport changed from 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.2: DONTNEED, 3.3: DONTNEED, 3.4: REQUIRED
I ran a bisect and as suspected this regression was caused by the forward call optimization in https://github.com/ruby/ruby/commit/cdf33ed5f37f9649c482c3ba1d245f0d80ac01ce
Updated by Anonymous 11 days ago
- Status changed from Open to Closed
Applied in changeset git|886268856ba7c70a6eaf25eeb402e6ebed9e851e.
Fix bad NameError raised using sendforward instruction through vcall
If you called a VCALL method and the method takes forwarding arguments
and then you forward those arguments along using the sendforward instruction,
the method_missing class was wrongly chosen as NameError instead of NoMethodError.
This is because the VM looked at the CallInfo of the vcall and determined it needed
to raise NameError. Now we detect that case and raise NoMethodError.
Fixes [Bug #21535]
Updated by alanwu (Alan Wu) 11 days ago
- Backport changed from 3.2: DONTNEED, 3.3: DONTNEED, 3.4: REQUIRED to 3.2: DONTNEED, 3.3: DONTNEED, 3.4: DONE
Backport for 3.4 done in 0d367ce65fe4e85f207a8ca5f1f331dd90c6992e