Fix the scope and argument binding of a lambda literal - #490
Merged
Merged
Conversation
A block or lambda with an empty body built its DummyNilNode with the
enclosing LocalEnv, and install0 takes the body's LocalEnv as its own.
So `->(x) { }` bound x in the enclosing scope, and an empty lambda took
the enclosing method's return and the enclosing block's break as the
value #call returns. An empty block had the same bug before a lambda
literal was analyzed at all.
A method with no keyword parameters takes `f(k: 1)` as a trailing
positional hash, but a lambda call skipped that step and reported
`->(h) { h }.call(k: 1)` as a wrong number of arguments.
A method call binds the block it is given to its `&b` parameter, but a lambda call left that parameter untyped. Proc#call already receives the block, so it is bound the same way.
A lambda given with `&` to an RBS-declared method was still bound like a block: its rest and post parameters got nothing and its arity was not checked, while the same lambda called with #call bound fully.
parse_params builds nodes for keyword defaults, but in a block they
were never installed, so a call in `{ |x: helper(1)| }` got no
diagnostics. A block still does not bind keywords.
The block of `super() { ... }` used to fall through to a debug `pp` in
wrong_return_type and report nothing.
sinsoku
force-pushed
the
lambda-method-args-fixes
branch
from
September 26, 2026 17:25
14752fb to
b4061a6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation / Background
This Pull Request has been created because reviewing #481 after it merged turned up five defects:
Detail
One commit per defect, in the order above.
DummyNilNodewith the enclosingLocalEnv, whichinstall0then takes as the block's own scope.Proc#callreceives the block it is given, but nothing bound it to&b.&still went through the block-shaped binder, which knows only positionals and checks no arity.LambdaNodelisted keyword defaults as subnodes, so in a block nothing installed the nodesAST.parse_paramshad built.A block still does not bind keywords; only the default expression is analyzed.
lambda {},proc {}andProc.new {}loseType::Procthrough their RBS declarations, so none of the argument binding reaches them.The last commit fixes nothing: it covers the block of
super() { ... }, which #481 made report a return type mismatch instead of printing the node class fromwrong_return_type.Verification
rake testpasses at every commit, and each added scenario, except the one forsuper, fails on the commit before its fix.🤖 Generated with Claude Code