Skip to content

Conversation

@thomasmarshall
Copy link

This PR fixes a crash when using Sorbet with Prism on the following code:

case
in x
end

This is invalid because a predicate is necessary for matching on. The original parser desugars this like so:

class <emptyTree><<C <root>>> < (::<todo sym>)
  if ::T.unsafe(::Kernel).raise("Sorbet rewriter pass partially unimplemented")
    begin
      x = ::T.unsafe(::Kernel).raise("Sorbet rewriter pass partially unimplemented")
      ::T.unsafe(::Kernel).raise("Sorbet rewriter pass partially unimplemented")
    end
  else
    <emptyTree>
  end
end

In the Prism translator we can check if the predicate desugars as an empty tree and return the expression early:

class <emptyTree><<C <root>>> < (::<todo sym>)
  if ::T.unsafe(::Kernel).raise("Sorbet rewriter pass partially unimplemented")
    begin
      x = ::T.unsafe(::Kernel).raise("Sorbet rewriter pass partially unimplemented")
      <emptyTree>
    end
  else
    <emptyTree>
  end
end

This is slightly different, we end up with <emptyTree> in place of ::T.unsafe(::Kernel).raise("Sorbet rewriter pass partially unimplemented"), but it seems to me a fine way to handle this. We could try to return a RaiseUnimplemented node here to match the original parser, but that seems wrong in the context—this is invalid code, not an unimplemented feature.

However, the error message for Prism is much better:

test/prism_regression/invalid/case_match_missing_predicate.rb:4: expected a predicate for a case matching statement https://srb.help/2001
     4 |case
        ^^^^
Errors: 1

Compared with this for the original parser:

test/prism_regression/invalid/case_match_missing_predicate.rb:4: unexpected token "case" https://srb.help/2001
     4 |case
        ^^^^

test/prism_regression/invalid/case_match_missing_predicate.rb:6: unexpected token "end" https://srb.help/2001
     6 |end
        ^^^
Errors: 2

@thomasmarshall
Copy link
Author

Oops didn't mean to assign you, meant to add you as reviewers.

@thomasmarshall thomasmarshall force-pushed the fix-missing-predicate-case branch from 1d382f8 to e0ba200 Compare December 19, 2025 16:41
@amomchilov amomchilov force-pushed the desugar-remaining branch 2 times, most recently from d96acf3 to 7f35d5d Compare December 19, 2025 19:25
```ruby
case
in x
end
```

This is invalid Ruby because the predicate is missing. The original
parser interprets the invalid code differently and ends up with a
`RaiseUnimplemented` node, but in our case we can use `EmptyTree`
to handle this instead, since it's not an unimplemented feature, it's
invalid syntax.
@thomasmarshall thomasmarshall force-pushed the fix-missing-predicate-case branch from e0ba200 to 4588336 Compare January 7, 2026 12:33
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.

3 participants