Description
Describe the bug
Running the following code:
f() ->
<<0 || _ <- [], _ <- ok, false>>.
wrapper0() ->
io:format("~kp", [catch f()]).
by doing
erlc -W0 ~/minimized/test237800.erl
erl -pa . -noshell -s test237800 wrapper0 -s init stop
results in the following output:
{'EXIT',{{bad_generator,ok},
[{test237800,f,0,
[{file,"/home/rmorisset/minimized/test237800.erl"},
{line,9}]},
{test237800,wrapper0,0,
[{file,"/home/rmorisset/minimized/test237800.erl"},
{line,12}]},
{init,start_em,1,[]},
{init,do_boot,3,[]}]}}
But adding +no_copt
to erlc insteads makes it output <<>>
.
Expected behavior
I don't know exactly which behavior is correct: should generators and filters be checked even after an empty generator?
I could not find anything about this question in the documentation (https://www.erlang.org/doc/reference_manual/expressions.html#comprehensions), beyond the following sentence:
A bit string comprehension returns a bit string, which is created by concatenating the results of evaluating BitStringExpr for each combination of bit string generator elements for which all filters are true
But since later generators can shadow variables in earlier ones, I expected them to be evaluated left to right.
It is possible that both behaviors are allowed on purpose, but in that case I'd like to suggest a warning in the documentation as it is a very non-obvious (and in my view not very useful) source of non-determinism.
Affected versions
master