-
Notifications
You must be signed in to change notification settings - Fork 35
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
Check exhaustiveness argument-wise #391
Check exhaustiveness argument-wise #391
Conversation
This enables checking exhaustiveness of functions of arity > 1 when some of the arguments cannot be checked for exhaustiveness.
I didn't read the code, but it's good to keep in mind that the arguments of a function clause can be treated as a tuple. I.e. |
They can, but should they always be? |
Yes, I think they're equivalent. That said, a free variable or Your example should be equally exhanstiveness-checking-enabled if all the args are wrapped in a tuple, don't you agree? -type message() :: {echo_rec, any()} | {hello, any()}.
-spec handle({message(), any(), any()}) -> state().
handle({{echo_req, Payload} = Req, From, State}) ->
gen_server:reply(From, Req),
State;
handle({{hello, Name}, From, State}) ->
io:format("Hello ~s!~n", [Name]),
gen_server:reply(From, ok),
State. |
No, that's the whole point.
The example is actually a snippet taken from a bigger demo which you can check out at https://github.com/esl/gradient/blob/14ea6a70bef46f5b7e5ecb26cbedd9c1d989fb9c/examples/typed_gen_server/lib/typed_gen_server/stage1.ex#L55-L67. |
I suppose you're right. For refinement, the args are equivalent to a tuple but for exhaustiveness they're separate. Thanks for convincing me. |
This enables checking exhaustiveness of functions of arity > 1 when some of the arguments cannot be
checked for exhaustiveness.
Consider the following example (Elixir syntax, but the problem is NOT Elixir specfic):
Without this PR this function cannot be checked for exhaustiveness because arguments of type
any
are not refinable. However, the 2nd and 3rd arguments are not used for control flow and are not pattern matched on, so it's not useful to check if the function clauses exhaust them.With this PR the exhaustiveness check is more flexible - it's up to the programmer to specify only some of the arguments to a level precise enough for exhaustiveness checking. Other, underspecified args, won't prevent the check from running on the well-specified ones.