Skip to content

Fix RBS rewriter for methods with anonymous keyword/positional rest params#977

Closed
rafaelfranca wants to merge 1 commit into
mainfrom
rm-fix-anon
Closed

Fix RBS rewriter for methods with anonymous keyword/positional rest params#977
rafaelfranca wants to merge 1 commit into
mainfrom
rm-fix-anon

Conversation

@rafaelfranca

@rafaelfranca rafaelfranca commented Jul 15, 2026

Copy link
Copy Markdown
Member

When a method definition uses anonymous rest params (e.g. def resolve(**) or def resolve(*)), the RBS-to-Sorbet sig translation produced invalid output: sig { params(**kwargs: ::T.untyped)... } -- a SyntaxError that
prevented the entire file from loading.

Root cause: RBI::RBS::MethodTypeTranslator falls back to the RBI parser's synthetic names (**kwargs, *args) for anonymous rest params. These splat-prefixed names are invalid in Sorbet sig params.

Fix: When the method def has anonymous ** or * (detected via Prism), the rewriter normalizes the corresponding translated SigParam names to quoted star names ("**" / "*") so the RBI printer emits
params("**": ...) / params("*": ...).

sorbet-runtime accepts these quoted star names as sig param names for anonymous rest params, so the sig binds correctly without rewriting the method def. This means anonymous forwarding expressions in the body
(e.g. g(**) or g(*)) remain valid Ruby -- no body rewriting needed.

RBS param names are non-semantic, so even when the RBS type names the param (e.g. (**untyped kwargs)), the sig uses the quoted star name to match the anonymous method def param.

The normalization is applied per translated signature, so malformed RBS leaves the method untouched (no sig emitted, no changes).

@rafaelfranca rafaelfranca requested a review from a team as a code owner July 15, 2026 17:26
Comment thread lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb Outdated
@rafaelfranca rafaelfranca force-pushed the rm-fix-anon branch 5 times, most recently from 358a639 to 1831996 Compare July 15, 2026 18:18
…arams

When a method definition uses anonymous rest params (e.g. `def resolve(**)`
or `def resolve(*)`), the RBS-to-Sorbet sig translation produced invalid
output: `sig { params(**kwargs: ::T.untyped)... }` -- a SyntaxError that
prevented the entire file from loading.

Root cause: RBI::RBS::MethodTypeTranslator falls back to the RBI parser's
synthetic names (`**kwargs`, `*args`) for anonymous rest params. These
splat-prefixed names are invalid in Sorbet sig params.

Fix: When the method def has anonymous `**` or `*` (detected via Prism),
the rewriter normalizes the corresponding translated SigParam names to
quoted star names (`"**"` / `"*"`) so the RBI printer emits
`params("**": ...)` / `params("*": ...)`.

sorbet-runtime accepts these quoted star names as sig param names for
anonymous rest params, so the sig binds correctly without rewriting the
method def.  This means anonymous forwarding expressions in the body
(e.g. `g(**)` or `g(*)`) remain valid Ruby -- no body rewriting needed.

RBS param names are non-semantic, so even when the RBS type names the
param (e.g. `(**untyped kwargs)`), the sig uses the quoted star name to
match the anonymous method def param.

The normalization is applied per translated signature, so malformed RBS
leaves the method untouched (no sig emitted, no changes).
@rafaelfranca

Copy link
Copy Markdown
Member Author

I left & out and change the approach to use string as keys

@Morriar

Morriar commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@rafaelfranca I think Shopify/rbi#624 is a better approach

@rafaelfranca

Copy link
Copy Markdown
Member Author

Yes. I'm fine with that

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