Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorbet does not statically check return types of lambda / proc arguments #3914

Open
jez opened this issue Jan 20, 2021 · 1 comment
Open
Labels
bug Something isn't working
Milestone

Comments

@jez
Copy link
Collaborator

jez commented Jan 20, 2021

Input

→ View on sorbet.run

# typed: true
T.let(-> {0}, T.proc.returns(String))

Observed output

No errors! Great job.

Expected behavior

The return lambda returns an Integer, but the type annotation declares that it should return a String, so Sorbet should report a type error statically.


I'm fine calling this bug closed after only solving the return type problem.

But note that checking argument types is trickier still:

→ View on sorbet.run

# typed: true
T.let(-> (x) {T.reveal_type(x)}, T.proc.params(x: Integer).void)

Observed output

editor.rb:2: Revealed type: T.untyped https://srb.help/7014
     2 |T.let(-> (x) {T.reveal_type(x)}, T.proc.params(x: Integer).void)
                      ^^^^^^^^^^^^^^^^
  Got T.untyped originating from:
    editor.rb:2:
     2 |T.let(-> (x) {T.reveal_type(x)}, T.proc.params(x: Integer).void)
                  ^
Errors: 1

In the CFG, Sorbet infers a type for the whole proc before it sees the Cast instruction which it could seemingly use to annotate the argument types when checking the body of the lambda.

Since it comes after, it picks T.untyped for the argument types when inferring a type for the the lambda.

@jez jez added the bug Something isn't working label Jan 20, 2021
@jez
Copy link
Collaborator Author

jez commented Apr 15, 2021

This is the same issue as #4149. That one has more test cases, this one has better context.

@jez jez added this to the Generics milestone Jul 23, 2022
jez added a commit that referenced this issue Mar 1, 2024
Partial fix for #3914
Partial fix for #4149
@jez jez mentioned this issue Mar 1, 2024
1 task
jez added a commit that referenced this issue Mar 1, 2024
Partial fix for #3914
Partial fix for #4149
jez added a commit that referenced this issue Apr 25, 2024
Sometimes it's useful to be able to use the arity of the block to guess
an overload.

This isn't perfect for all the reasons that overload checking isn't
perfect, but there are some places where this is useful, especially in
abstractions that check the proc's arity when deciding how to call the
block.

This is also a pre-requisite for doing something like #7741, which is a
partial fix for #3914 / #4149, where we infer the types of
`Kernel#lambda` blocks by codegenerating overloaded signatures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant