Skip to content

Fix crash on anonymous splat in find pattern and {**nil} - #465

Merged
sinsoku merged 2 commits into
ruby:masterfrom
ahogappa:fix-pattern-matching-crashes
Aug 12, 2026
Merged

Fix crash on anonymous splat in find pattern and {**nil}#465
sinsoku merged 2 commits into
ruby:masterfrom
ahogappa:fix-pattern-matching-crashes

Conversation

@ahogappa

@ahogappa ahogappa commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Two pattern-matching forms crash during AST construction on master:

case ary
in [*, x, *rest]
  x
end
# => lib/typeprof/core/ast.rb:334:in 'create_pattern_node':
#    undefined method 'type' for nil (NoMethodError)
case h
in {**nil}
  1
end
# => lib/typeprof/core/ast/pattern.rb:42:in 'initialize':
#    undefined method 'value' for an instance of Prism::NoKeywordsParameterNode

Prism represents an anonymous splat as a SplatNode whose expression is nil, and HashPatternNode#rest can be a NoKeywordsParameterNode, which has no value. Both were passed to AST.create_pattern_node unchecked. ArrayPatternNode already guards against these, so this applies the same handling to FindPatternNode and HashPatternNode.

ahogappa and others added 2 commits August 11, 2026 08:14
Prism represents an anonymous splat as a `SplatNode` whose `expression`
is nil, so `FindPatternNode#initialize` passed nil into
`AST.create_pattern_node` and crashed with:

    undefined method 'type' for nil (NoMethodError)
    lib/typeprof/core/ast.rb:334:in 'AST.create_pattern_node'
    lib/typeprof/core/ast/pattern.rb:61:in 'FindPatternNode#initialize'

`left` and `right` are never nil (the grammar requires both splats), so
check `expression` instead, as `ArrayPatternNode` already does for its
rest pattern.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`HashPatternNode#rest` is `AssocSplatNode | NoKeywordsParameterNode |
nil`, but the code assumed it always responds to `value`, so `in {**nil}`
crashed with:

    undefined method 'value' for an instance of Prism::NoKeywordsParameterNode
    lib/typeprof/core/ast/pattern.rb:42:in 'HashPatternNode#initialize'

Dispatch on the node class, mirroring `ArrayPatternNode#initialize`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@sinsoku sinsoku left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@sinsoku
sinsoku merged commit d85989a into ruby:master Aug 12, 2026
6 checks passed
@ahogappa
ahogappa deleted the fix-pattern-matching-crashes branch August 13, 2026 02:15
ahogappa pushed a commit to ahogappa/ryac that referenced this pull request Aug 13, 2026
ruby/typeprof#465 (merged upstream) fixes the anonymous-splat find
pattern and `**nil` hash pattern crashes; #451 fixed parameterless
block pipes. The blanket find-pattern guard was both too broad (NAMED
splat find patterns ingest fine on 0.32.0 and now minify — corpus and
pins cover them) and too narrow (`**nil` and `{ || }` crashed
unguarded).

The pre-scan raise is gone. update_rb_file is wrapped instead: a
typeprof that ingests a shape just analyzes it; one that crashes gets
the crash converted to a MinifyError naming the construct and line.
The analyzer tests pin that contract for all three hazard shapes, so
when the Gemfile's typeprof carries the fixes the success path
activates with no further change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016BMPhxTBHdPWT7UyraSLaD
ahogappa pushed a commit to ahogappa/ryac that referenced this pull request Aug 13, 2026
…ments

The Gemfile moves typeprof to master, which carries the ingestion fixes
for anonymous-splat find patterns and `**nil` (ruby/typeprof#465) and
parameterless block pipes (#451); the corpus now exercises all three
and the pins are regenerated under that typeprof. The gemspec still
admits released 0.32.0, where the analyzer names these constructs in a
MinifyError instead.

alias/undef rendering goes through r_alias_name: plain symbols keep
dropping the colon, and an interpolated symbol keeps its own syntax
instead of crashing on a missing #value.

The type-repair prose comments are cut down to the invariant they
protect; narration about what the type checker does or fails to see is
gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016BMPhxTBHdPWT7UyraSLaD
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.

2 participants