8000 Fix runtime exception with unused optional and rest parameters. by alto-rlk · Pull Request #5475 · sorbet/sorbet · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix runtime exception with unused optional and rest parameters. #5475

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

Merged
merged 1 commit into from
Mar 16, 2022

Conversation

alto-rlk
Copy link
Contributor

This PR fixes an exception that occurs in sorbet-runtime when a method that accepts both optional and rest/splat parameters is called with neither.

Motivation

Given a typed method definition such as:

sig {params(x: Integer, rest: Integer).void}
def foo(x = 0, *rest)
end

If the method is called with no parameters, an ArgumentError will be raised at

arg_types += [[@rest_name, @rest_type]] * (args_length - @arg_types.length)

due to (args_length - @arg_types.length) being negative.

This PR constrains the above result to a minimum of zero, in which case nothing is added to arg_types.

Test plan

See included automated tests.

@alto-rlk alto-rlk requested a review from a team as a code owner March 16, 2022 00:33
@alto-rlk alto-rlk requested review from jez and removed request for a team March 16, 2022 00:33
@jez
Copy link
Collaborator
jez commented Mar 16, 2022

Thanks for the PR. I'm testing this change on Stripe's codebase to see if anything breaks. I'll let you know the results, and merge if it passes.

Comment on lines +185 to +188
rest_count = args_length - @arg_types.length
rest_count = 0 if rest_count.negative?

arg_types += [[@rest_name, @rest_type]] * rest_count
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could just be:

Suggested change
rest_count = args_length - @arg_types.length
rest_count = 0 if rest_count.negative?
arg_types += [[@rest_name, @rest_type]] * rest_count
rest_count = (args_length - @arg_types.length).clamp(0..nil)
arg_types += [[@rest_name, @rest_type]] * rest_count

by the way, or:

Suggested change
8000
rest_count = args_length - @arg_types.length
rest_count = 0 if rest_count.negative?
arg_types += [[@rest_name, @rest_type]] * rest_count
rest_count = [args_length - @arg_types.length, 0].max
arg_types += [[@rest_name, @rest_type]] * rest_count

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah, i don't mind the code being written either way and i already tested the code as written on Stripe's codebase, so i'm inclined to ship it as is (lest by some oversight the two aren't as equivalent as we think they are).

Copy link
Collaborator
@jez jez left a comment

Choose a reason for hiding this comment

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

thanks for the test

@jez jez merged commit 1409470 into sorbet:master Mar 16, 2022
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
0