If we pass ClosureInfo that indicates that a lambda captures, then when
we extend the lambda's argument list with the lambda set it appears it,
the extension must necessarily be material.
Previously, if the lambda set passed to a HOLL contained any function
that captured, we would assume that the specialization of the HOLL we
should make for each function in the lambda set that we dispatch to
should capture.
This is not right. Instead, we should specialize for each lambda in the
set passed to the HOLL. The present patch enforces that, making sure
that for each lambda in the set, we compute the exact proc layout needed
to call the lambda, based on the captures of the specific lambda in the
set, rather than looking at the set entirely.
Previously, we determined whether a closure argument should be added to
the proc layout of a compiled function by checking whether the lambda
set was material at all. But, the extension for a single function should
be added if and only if the function itself captures.
* test_fmt moves out of fmt crate
* test_parse _mostly_ moves out of parse crate and into `test_snapshots.rs` (some simple tests remain)
* now there's only two fuzz targets, fuzz_expr and fuzz_module, that cover both parsing and formatting
* added a system to auto-add new snapshot entries for new test files
* took some commented-out tests in `test_parse` and converted them to snapshot tests
* moved test_fmt's verification of formatting consistency into test_snapshots
* fixed a huge derp on my part where the fmt fuzzer in #4758 was completely useless (broken by refactoring just prior to submitting the PR)
* fixed a formatting bug found by fuzzing (bound_variable.expr.roc) - that I missed earlier due to ^^^ that derp
* no longer have roc_test_utils as a dependency in fmt - which was causing problems for the wasm build
Some of the head-constructor tests we generate can be supersets of other tests.
Edges must be ordered so that more general tests always happen after their
specialized variants.
For example, patterns
[1, ..] -> ...
[2, 1, ..] -> ...
may generate the edges
ListLen(>=1) -> <rest>
ListLen(>=2) -> <rest>
but evaluated in exactly this order, the second edge is never reachable.
The necessary ordering is
ListLen(>=2) -> <rest>
ListLen(>=1) -> <rest>
Closes#4732