Inline in empty list in erlang pass#15413
Conversation
| assert typecheck!( | ||
| [x], | ||
| x in [] | ||
| ) == boolean() |
There was a problem hiding this comment.
It feels we should be able to narrow it to false (in which case we'd still have a warning, just more helpful), but right now it's consistent with :foo in [:bar] not warning.
There was a problem hiding this comment.
On apply.ex, you can replace this:
{:lists, :member, [{[term(), list(term())], boolean()}]},
with this:
{:lists, :member, [{[term(), empty_list()], atom([false])}, {[term(), non_empty_list(term())], boolean()}]},
| ]}, VS}; | ||
| translate_remote(lists, member, Meta, [_Expr, []], S) -> | ||
| Ann = ?ann(Meta), | ||
| {{atom, Ann, false}, S}; |
There was a problem hiding this comment.
We need to execute the expression in case of side-effects, so it has to be something like before:
| {{atom, Ann, false}, S}; | |
| {{block, Ann, [{match, Ann, {var, Ann, '_'}, Expr}, {atom, Ann, false}]}, S}; |
Shall we add a test to the test/erlang/* files? I think we test other optimizations there already.
There was a problem hiding this comment.
Or even better, perhaps a test for Kernel.in/2 like this:
false = send(self(), :hello) in []
assert_received :hello
josevalim
left a comment
There was a problem hiding this comment.
I dropped some comments.
We also need to replace this in types/helpers.ex:
{{:., _, [:lists, :member]}, meta, [expr, [_ | _] = args]} = call ->
if Enum.any?(args, &match?({:|, _, [_, _]}, &1)) do
call
else
{:in, meta, [expr, args]}
end
by this:
{{:., _, [:lists, :member]}, meta, [expr, args]} = call when is_list(args) ->
if Enum.any?(args, &match?({:|, _, [_, _]}, &1)) do
call
else
{:in, meta, [expr, args]}
end
You can add some tests to types/helper_test.exs for in (currently no coverage).
|
Thanks for all the pointers @josevalim 💜 OK, with 58a96ee we're back with a warning but a readable one:
|

x in []is expanded at:lists.member(x, [])falseSame approach as 34a5000
Closes #15411