Example session:
```
» 1 + 1
The Roc compiler had an internal error.
Please file a bug report at
https://github.com/roc-lang/roc/issues/new
Please include the following data:
Error message: intentional panic
Stack backtrace:
0: std::backtrace_rs::backtrace::libunwind::trace
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/../../backtrace/src/backtrace/libunwind.rs:104:5
1: std::backtrace_rs::backtrace::trace_unsynchronized
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: std::backtrace::Backtrace::create
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/backtrace.rs:331:13
3: panic_hook
at ./crates/repl_cli/src/lib.rs:52:41
4: call<fn(&core::panic::panic_info::PanicInfo), (&core::panic::panic_info::PanicInfo)>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:79:5
5: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/alloc/src/boxed.rs:2029:9
6: std::panicking::rust_panic_with_hook
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:785:13
7: std::panicking::begin_panic_handler::{{closure}}
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:651:13
8: std::sys_common::backtrace::__rust_end_short_backtrace
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/sys_common/backtrace.rs:171:18
9: rust_begin_unwind
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:647:5
10: core::panicking::panic_fmt
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panicking.rs:72:14
11: step
at ./crates/repl_ui/src/repl_state.rs:66:9
12: {closure#1}
at ./crates/repl_cli/src/lib.rs:109:21
13: call_once<roc_repl_cli::main::{closure_env#1}, ()>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:250:5
14: call_once<roc_repl_ui::repl_state::ReplAction, roc_repl_cli::main::{closure_env#1}>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panic/unwind_safe.rs:272:9
15: do_call<core::panic::unwind_safe::AssertUnwindSafe<roc_repl_cli::main::{closure_env#1}>, roc_repl_ui::repl_state::ReplAction>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:554:40
16: ___rust_try
17: try<roc_repl_ui::repl_state::ReplAction, core::panic::unwind_safe::AssertUnwindSafe<roc_repl_cli::main::{closure_env#1}>>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:518:19
18: catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<roc_repl_cli::main::{closure_env#1}>, roc_repl_ui::repl_state::ReplAction>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panic.rs:142:14
19: main
at ./crates/repl_cli/src/lib.rs:108:30
20: main
at ./crates/cli/src/main.rs:321:16
21: call_once<fn() -> core::result::Result<(), std::io::error::Error>, ()>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:250:5
22: __rust_begin_short_backtrace<fn() -> core::result::Result<(), std::io::error::Error>, core::result::Result<(), std::io::error::Error>>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/sys_common/backtrace.rs:155:18
23: {closure#0}<core::result::Result<(), std::io::error::Error>>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:166:18
24: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:284:13
25: std::panicking::try::do_call
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:554:40
26: std::panicking::try
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:518:19
27: std::panic::catch_unwind
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panic.rs:142:14
28: std::rt::lang_start_internal::{{closure}}
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:148:48
29: std::panicking::try::do_call
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:554:40
30: std::panicking::try
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:518:19
31: std::panic::catch_unwind
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panic.rs:142:14
32: std::rt::lang_start_internal
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:148:20
33: lang_start<core::result::Result<(), std::io::error::Error>>
at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/rt.rs:165:17
34: _main
Machine Target: MacArm64
```
This new flag determines whether we should introduce a new kind to
represent lambda sets, or whether lambdas should be erased. The latter
is not yet implemented.
In the llvm backend, there are the lifetimes `'a` (lifetime of the
global arena) and `'ctx` (lifetime of constructed LLVM values). `'a`
lives longer than `'ctx`, but the compiler didn't enforce this until
the layout interner was introduced, for some reason. We have to make
sure that containers of lifetime `'a` have no `'ctx` references.
This commit adds fuzzing for the (expr) formatter, with the same invariants that we use for fmt tests:
* We start with text, which we parse
* We format the AST, which must succeed
* We parse back the AST and make sure it's identical igoring whitespace+comments
* We format the new AST and assert it's equal to the first formatted version ("idempotency")
Interestingly, while a lot of bugs this found were in the formatter, it also found some parsing bugs.
It then fixes a bunch of bugs that fell out:
* Some small oversights in RemoveSpaces
* Make sure `_a` doesn't parse as an inferred type (`_`) followed by an identifier (parsing bug!)
* Call `extract_spaces` on a parsed expr before matching on it, lest it be Expr::SpaceBefore - when parsing aliases
* A few cases where the formatter generated invalid/different code
* Numerous formatting bugs that caused the formatting to not be idempotent
The last point there is worth talking further about. There were several cases where the old code was trying to enforce strong
opinions about how to insert newlines in function types and defs. In both of those cases, it looked like the goals of
(1) idempotency, (2) giving the user some say in the output, and (3) these strong opinions - were often in conflict.
For these cases, I erred on the side of following the user's existing choices about where to put newlines.
We can go back and re-add this strong opinionation later - but this seemed the right approach for now.