Kernel#send doesn't work with splat blocks - #68
Open
apiology wants to merge 3 commits into
Open
Conversation
The Kernel#send RBS block signature is a real splat -
(*arg ::Array) -> untyped - meaning "however many values the
dynamically-dispatched method yields," not "one value, typed as an
Array, was yielded." Block::typify_parameters treated that single
splat parameter's return_type the same as a genuine single yielded
value, so a .send(...) { |name| ... } block bound the whole Array
type to name instead of leaving it undefined.
Ruby itself truncates to the first yielded value here; Solargraph
cannot know what .send actually dispatches to, so the correct
inference is undefined, not the whole Array.
destructure_yield_types now also takes the yielding method's own
block parameter pins (not just their types) so it can tell a lone
splat apart from a genuine single value, and falls back to
undefined for each declared block parameter unless the block itself
is also declared with a splat.
apiology
added a commit
that referenced
this pull request
Aug 27, 2026
Merge-resolved a conflict in pin/block.rb: two independent helper methods (per_position_yield_types? from an already-merged PR, and this PR's own single_unknown_arity_splat?) collided at the same insertion point; kept both. Removed 3 now-unneeded @sg-ignore markers this PR's branch had added. spec/pin/parameter_spec.rb:82 fails locally on this exact merge result, but also fails identically on the pre-merge tip (62eb9b6) with this PR's changes fully reverted, and CI's own rspec matrix (including the Ruby 3.2 combos matching local) already passed on that commit. Cause of the local-only failure is unknown; not caused by this merge.
apiology
added a commit
that referenced
this pull request
Aug 27, 2026
CI (Ruby 4.0) failed on the #68 merge with two typecheck findings that are the mirror image of what local Ruby 3.2.6 reported: typify_parameters' return-type-mismatch ignore, removed locally as unneeded, is still needed on 4.0; destructure_yield_types' own ignore, kept from #68's branch, is unneeded on 4.0 but was needed locally. Restored the first, removed the second, matching CI's verdict per this repo's standing local/CI disagreement convention.
Comments this PR added ran well past the repo's 1-3 line budget and included a multi-line @sg-ignore, against the single-line convention in lib/solargraph/type_checker/rules.rb. Condensed the destructure_yield_types docstring, its splat-detection inline comment, and the block_spec.rb #send example's comment to their core claims; no code or @type changes. Full original @sg-ignore text, preserved here since it was compressed in the source: Declared return type does not match inferred - adding the splat-detection return below changes how Solargraph merges this method's multiple return paths, and it now infers Enumerator instead of Array for the tail expression even though that expression is unchanged from before this method had more than one return path, when it typechecked cleanly. This may be worth filing upstream as a real Solargraph gap: merging multiple return paths of a method appears to infer Enumerator rather than Array for a tail expression that is otherwise unchanged.
apiology
marked this pull request as ready for review
September 7, 2026 01:00
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.
Problem:
Cause:
Pin::Block#typify_parameterstreated the splat'sreturn_typeas a genuine single yielded value, so the.send-dispatched block bound the wholeArrayto its parameter instead of leaving it undefined.Solution:
destructure_yield_typesnow also takes the yielding method's own block parameter pins, not just their resolved types, so a newsingle_unknown_arity_splat?check can tell a lone splat (*arg) apart from a genuine single yielded value.When it fires, every declared block parameter is left
UNDEFINEDinstead of bound to the wholeArray.Claude: opened on behalf of the repo owner while auditing
@sg-ignoresuppressions in a downstream project.