Fix initialize return type when sig uses .void.checked(:tests)#2579
Open
dduugg wants to merge 1 commit intoShopify:mainfrom
Open
Fix initialize return type when sig uses .void.checked(:tests)#2579dduugg wants to merge 1 commit intoShopify:mainfrom
dduugg wants to merge 1 commit intoShopify:mainfrom
Conversation
When a Sorbet sig uses `.void.checked(:tests)`, the Sorbet runtime introspects the return type as `T::Types::Anything` outside of test mode. Tapioca then serialized this as `returns(T.anything)` in the generated gem RBI, which is invalid — `initialize` must always return void. Fix `SorbetSignatures#on_method` to always emit `void` as the return type for `initialize` methods, regardless of what the signature's return type introspects to.
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
When a Sorbet sig uses
.void.checked(:tests), the Sorbet runtime introspects thereturn_typeasT::Types::Anythingoutside of test mode. Tapioca then serializes this asreturns(T.anything)in the generated gem RBI, which is invalid —initializemust always returnvoidin Sorbet.This produces RBI files that fail the
Sorbet/InitializeShouldReturnVoidRuboCop cop, causing pre-commit hook failures for anyone runningtapioca gemson a codebase that uses.void.checked(:tests)oninitialize.Repro:
Note:
.void.checked(:tests)causesT.anythingto be introspected as the return type for any method with that sig pattern, not justinitialize. However, onlyinitializeproduces a hardsrb tcfailure (Sorbet requires it to return void). There is no stable Sorbet API to distinguish "declared void, introspected asT.anything" for other methods, so the broader case is out of scope here.Implementation
In
SorbetSignatures#on_method, after compiling the sig, unconditionally setreturn_typeto"void"when the method isinitialize. Since Sorbet requiresinitializeto always return void, this is always correct regardless of what the signature's return type introspects to.Tests
Added a spec case to
pipeline_spec.rbcovering aninitializemethod with.void.checked(:tests), asserting the generated RBI emitsvoid.