Skip to content

Fix the arguments and the lookup of super - #492

Draft
sinsoku wants to merge 2 commits into
ruby:masterfrom
sinsoku:fix-bare-super-arguments
Draft

sinsoku wants to merge 2 commits into
ruby:masterfrom
sinsoku:fix-bare-super-arguments

Conversation

@sinsoku

@sinsoku sinsoku commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation / Background

This Pull Request has been created because TypeProf reports valid calls of super as errors.

class A
  def foo(x, y) = [x, y]
  def bar(x) = x
end
class B < A
  def foo(x = 0, y = "str")
    super             # wrong number of arguments (0 for 2)
  end
  def bar(x)
    [1].map { super } # undefined method: B#map
  end
end
B.new.foo
B.new.bar(1)

Detail

  • A bare super passes the current values of the parameters, including defaults and reassignments, but TypeProf forwarded only what the caller gave, sharing the implementation of ... (Handle mixed and omitted forwarded arguments #434). ... and anonymous or destructured parameters are still forwarded that way, as they have no variable the method can reassign. A keyword default also did not reach the parent when the method had a named **rest that stayed empty, as the box merging the keywords into it never ran.
  • A block took the name of the method it was passed to, so super in it looked up map. It now passes the variables of the method even where a block parameter shadows them. A super outside any method, such as in a define_method block in a class body, now skips the lookup, so it is no longer reported as an undefined method.

Verification

The example above reports no errors and infers A#foo: (Integer, String) and A#bar: (Integer). Each added scenario fails on the commit before its fix.

🤖 Generated with Claude Code

@sinsoku
sinsoku force-pushed the fix-bare-super-arguments branch 2 times, most recently from 988250d to 5e6ad0c Compare September 27, 2026 14:29
@sinsoku
sinsoku marked this pull request as draft September 27, 2026 15:18
@sinsoku
sinsoku force-pushed the fix-bare-super-arguments branch 2 times, most recently from d146108 to 10136d5 Compare September 27, 2026 16:22
A bare `super` passes the current values of the parameters, including
defaults and reassignments, but TypeProf forwarded only what the caller
gave, as `...` does. So `def foo(x = 0) = super` called without
arguments was reported as a wrong number of arguments for the parent.

`...` and anonymous or destructured parameters have no variable the
method can reassign, so they are still forwarded as given. A block or
lambda parameter can shadow a parameter of the method, so a `super` in
it still passes the variable of the method.

A named `**rest` that stays empty never ran the box merging the keywords
into it, so a keyword default did not reach the parent either. The box
now runs once when it is created.
A block took the name of the method it was passed to, so
`[1].map { super }` in `def foo` looked up `map` instead of `foo`. It
now takes the name of the enclosing method, as a lambda literal already
did.

A block outside any method then has no method name, so its `super` is
skipped instead of reported as an undefined method with an empty name.
A block given to define_method or define_singleton_method is the body
of another method, so it has no method name either, and a bare `super`
in it is reported as not supported, as Ruby raises for it at runtime.
@sinsoku
sinsoku force-pushed the fix-bare-super-arguments branch from 10136d5 to 9dc5adb Compare September 27, 2026 17:18

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant