Skip to content

+no_copt changes the result of a comprehension #7494

Closed
@RobinMorisset

Description

@RobinMorisset

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

Metadata

Metadata

Assignees

Labels

bugIssue is reported as a bugteam:VMAssigned to OTP team VM

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions