From 9161de8e1fd093ec67cd57bbe28faacacb0825b2 Mon Sep 17 00:00:00 2001 From: Anthony Bullard Date: Fri, 20 Dec 2024 05:15:47 -0600 Subject: [PATCH 01/14] Better tablet support for docs --- crates/docs/src/static/styles.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/docs/src/static/styles.css b/crates/docs/src/static/styles.css index 1399d5cf8b..1acc755059 100644 --- a/crates/docs/src/static/styles.css +++ b/crates/docs/src/static/styles.css @@ -200,7 +200,7 @@ main { overflow-wrap: break-word; overflow-y: auto; display: grid; - grid-template-columns: [main-start] 1fr [main-content-start] 60ch [main-content-end] 1fr [main-end]; + grid-template-columns: [main-start] minmax(16px,1fr) [main-content-start] minmax(calc(100% - 32px), 60ch) [main-content-end] minmax(16px,1fr) [main-end]; grid-template-rows: auto; flex-direction: column; scrollbar-color: var(--violet) var(--body-bg-color); @@ -697,7 +697,7 @@ pre>samp { } } -@media only screen and (max-device-width: 480px) and (orientation: portrait) { +@media only screen and (max-device-width: 768px) and (orientation: portrait) { body { display: block; overflow-y: auto; From 7d60cc8601d6004337c9f636e99639cb998d342f Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 21 Dec 2024 12:24:21 +0100 Subject: [PATCH 02/14] improve contributing.md UX Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0c6dab5572..bdb6c09e12 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,6 +68,8 @@ programs.gnupg.agent = {
Forgot to sign commits? +:exclamation: Make sure [to set up signing on your device](devtools/signing.md) first, then continue below. + You can view your commits on github, those without the "Verified" badge still need to be signed. If any of those is a merge commit, follow [these steps](https://stackoverflow.com/a/9958215/4200103) instead of the ones below. From ccc7071842026bd1f663b21a2adcd9a8215bcb02 Mon Sep 17 00:00:00 2001 From: Anthony Bullard Date: Sat, 21 Dec 2024 08:59:46 -0600 Subject: [PATCH 03/14] Better tablet layout, and syntax highlighted signatures --- crates/docs/src/lib.rs | 34 +++++++-- crates/docs/src/static/search.js | 66 +++++++++------- crates/docs/src/static/styles.css | 123 +++++++++++++++++++++++------- 3 files changed, 162 insertions(+), 61 deletions(-) diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs index 8a7c1a6a59..15e2d1e547 100644 --- a/crates/docs/src/lib.rs +++ b/crates/docs/src/lib.rs @@ -5,6 +5,7 @@ extern crate roc_load; use bumpalo::Bump; use roc_can::scope::Scope; use roc_collections::VecSet; +use roc_highlight::highlight_roc_code_inline; use roc_load::docs::{DocEntry, TypeAnnotation}; use roc_load::docs::{ModuleDocumentation, RecordField}; use roc_load::{ExecutionMode, LoadConfig, LoadedModule, LoadingProblem, Threading}; @@ -314,13 +315,15 @@ fn render_module_documentation( let def_name = doc_def.name.as_str(); let href = format!("{module_name}#{def_name}"); let mut content = String::new(); + let mut anno_buf = String::new(); push_html(&mut content, "a", [("href", href.as_str())], LINK_SVG); - push_html(&mut content, "strong", [], def_name); + // push_html(&mut content, "strong", [], def_name); + anno_buf.push_str(def_name); for type_var in &doc_def.type_vars { - content.push(' '); - content.push_str(type_var.as_str()); + anno_buf.push(' '); + anno_buf.push_str(type_var.as_str()); } let type_ann = &doc_def.type_annotation; @@ -328,13 +331,14 @@ fn render_module_documentation( if !matches!(type_ann, TypeAnnotation::NoTypeAnn) { // Ability declarations don't have ":" after the name, just `implements` if !matches!(type_ann, TypeAnnotation::Ability { .. }) { - content.push_str(" :"); + anno_buf.push_str(" :"); } - content.push(' '); + anno_buf.push(' '); - type_annotation_to_html(0, &mut content, type_ann, false); + type_annotation_to_html(0, &mut anno_buf, type_ann, false); } + content.push_str(highlight_roc_code_inline(anno_buf.as_str()).as_str()); push_html( &mut buf, @@ -460,12 +464,26 @@ fn render_sidebar<'a, I: Iterator>(modules: I) - for module in modules { let href = module.name.as_str(); let mut sidebar_entry_content = String::new(); + let mut module_link_content = String::new(); + + push_html(&mut module_link_content, "span", [], module.name.as_str()); + + push_html( + &mut module_link_content, + "button", + [("class", "entry-toggle")], + "▶", + ); push_html( &mut sidebar_entry_content, "a", - [("class", "sidebar-module-link"), ("href", href)], - module.name.as_str(), + [ + ("class", "sidebar-module-link"), + ("href", href), + ("data-module-name", module.name.as_str()), + ], + module_link_content.as_str(), ); let entries = { diff --git a/crates/docs/src/static/search.js b/crates/docs/src/static/search.js index e3190a2b55..d21d3eff0f 100644 --- a/crates/docs/src/static/search.js +++ b/crates/docs/src/static/search.js @@ -1,27 +1,34 @@ -(() => { +const toggleSidebarEntryActive = (moduleName) => { let sidebar = document.getElementById("sidebar-nav"); if (sidebar != null) { // Un-hide everything - sidebar - .querySelectorAll(".sidebar-entry a") - .forEach((entry) => entry.classList.remove("hidden")); - - // Re-hide all the sub-entries except for those of the current module - let currentModuleName = document.querySelector(".module-name").textContent; - sidebar.querySelectorAll(".sidebar-entry").forEach((entry) => { - let entryName = entry.querySelector(".sidebar-module-link").textContent; - if (currentModuleName === entryName) { - entry.firstChild.classList.add("active"); - return; + let entryName = entry.querySelector(".sidebar-module-link").dataset + .moduleName; + if (moduleName === entryName) { + entry.firstChild.classList.toggle("active"); } - entry - .querySelectorAll(".sidebar-sub-entries a") - .forEach((subEntry) => subEntry.classList.add("hidden")); }); } +}; +const setupSidebarNav = () => { + // Re-hide all the sub-entries except for those of the current module + let currentModuleName = document.querySelector(".module-name").textContent; + toggleSidebarEntryActive(currentModuleName); + + document.querySelectorAll(".entry-toggle").forEach((el) => { + el.addEventListener("click", (e) => { + e.preventDefault(); + e.stopImmediatePropagation(); + const moduleName = e.target.parentElement.dataset.moduleName; + toggleSidebarEntryActive(moduleName); + }); + }); +}; + +const setupSearch = () => { let searchTypeAhead = document.getElementById("search-type-ahead"); let searchBox = document.getElementById("module-search"); let searchForm = document.getElementById("module-search-form"); @@ -184,16 +191,18 @@ } }); } +}; - const isTouchSupported = () => { - try { - document.createEvent("TouchEvent"); - return true; - } catch (e) { - return false; - } - }; +const isTouchSupported = () => { + try { + document.createEvent("TouchEvent"); + return true; + } catch (e) { + return false; + } +}; +const setupCodeBlocks = () => { // Select all elements that are children of
 elements
   const codeBlocks = document.querySelectorAll("pre > samp");
 
@@ -245,9 +254,9 @@
       });
     }
   });
-})();
+};
 
-(() => {
+const setupSidebarToggle = () => {
   let body = document.body;
   const sidebarOpen = "sidebar-open";
   const removeOpenClass = () => {
@@ -267,4 +276,9 @@
       });
     },
   );
-})();
+};
+
+setupSidebarNav();
+setupSearch();
+setupCodeBlocks();
+setupSidebarToggle();
diff --git a/crates/docs/src/static/styles.css b/crates/docs/src/static/styles.css
index 1acc755059..a188e7f0a5 100644
--- a/crates/docs/src/static/styles.css
+++ b/crates/docs/src/static/styles.css
@@ -7,7 +7,7 @@
   --cyan: hsl(190 100% 18% / 1);
   --blue: #05006d;
   --violet: #7c38f5;
-  --violet-bg: hsl(262.22deg 87.1% 93.92%);
+  --violet-bg: hsl(262.22deg 87.1% 96%);
   --magenta: #a20031;
   --link-hover-color: #333;
   --link-color: var(--violet);
@@ -21,8 +21,8 @@
   --font-mono: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
   --top-header-height: 67px;
   --sidebar-width: clamp(280px, 25dvw, 500px);
-  --module-search-height: 48px;
-  --module-search-padding-height: 12px;
+  --module-search-height: 56px;
+  --module-search-padding-height: 16px;
   --module-search-form-padding-width: 20px;
   --sidebar-bg-color: hsl(from var(--violet-bg) h calc(s * 1.05) calc(l * 0.95));
 }
@@ -41,10 +41,6 @@ table tr td {
   padding: 6px 13px;
 }
 
-.logo {
-  padding: 2px 8px;
-}
-
 .logo svg {
   height: 48px;
   width: 48px;
@@ -81,13 +77,18 @@ table tr td {
   margin-top: 0;
   margin-bottom: 24px;
   padding: 12px 16px;
-  border: 2px solid var(--violet);
+  border-left: 4px solid var(--violet);
+  display: flex;
 }
 
 .entry-name strong {
     color: var(--text-color);
 }
 
+.entry-name code {
+    background: none;
+}
+
 .entry-name:target {
   background-color: var(--violet-bg);
 }
@@ -137,9 +138,7 @@ a:hover code {
   justify-content: flex-start;
   gap: 8px;
   background-color: var(--violet-bg);
-  padding-block: 16px;
-  position: sticky;
-  top: 0px;
+  padding: 16px;
 }
 
 .pkg-and-logo a,
@@ -200,7 +199,8 @@ main {
   overflow-wrap: break-word;
   overflow-y: auto;
   display: grid;
-  grid-template-columns: [main-start] minmax(16px,1fr) [main-content-start] minmax(calc(100% - 32px), 60ch) [main-content-end] minmax(16px,1fr) [main-end];
+  --main-content-width: clamp(100px, calc(100% - 32px), 60ch); 
+  grid-template-columns: [main-start] minmax(16px,1fr) [main-content-start] var(--main-content-width) [main-content-end] minmax(16px,1fr) [main-end];
   grid-template-rows: auto;
   flex-direction: column;
   scrollbar-color: var(--violet) var(--body-bg-color);
@@ -278,8 +278,9 @@ padding: 0px 16px;
     overflow-y: auto;
     overflow-x: hidden;
     scrollbar-color: var(--violet) var(--sidebar-bg-color);
-    scrollbar-gutter: stable both-edges;
-    padding-block: 1rem;
+    scrollbar-gutter: stable;
+    padding: 16px 8px;
+    transition: all .2s linear;
 }
 
 .top-header {
@@ -345,6 +346,11 @@ footer p {
 
 .sidebar-sub-entries {
     font-size: 12pt;
+    display: none;
+}
+
+.active + .sidebar-sub-entries {
+    display: block;
 }
 
 .sidebar-sub-entries a {
@@ -353,16 +359,28 @@ footer p {
   width: 100%;
   overflow: hidden;
   text-overflow: ellipsis;
-  margin-left: 14px;
+  margin-left: 20px;
   padding-left: 27px;
   border-left: 2px solid rgb(from var(--gray) r g b / .30);
   white-space: nowrap;
+  display: flex;
+  align-items: center;
+}
+
+.sidebar-sub-entries a:first-child {
+    margin-top: 8px;
+    padding-top: 0;
+}
+
+.sidebar-sub-entries a:last-child {
+    margin-bottom: 8px;
+    padding-bottom: 0;
 }
 
 .sidebar-sub-entries a:hover {
     border-left-color: rgb(from var(--violet) r g b / .60);
-    color: hsl(from var(--text-color) h s calc(l * 1.5));
-    background-color: rgb(from white r g b / .10);
+    color: var(--violet);
+    text-decoration: none;
 }
 
 .module-name {
@@ -394,23 +412,64 @@ color: inherit;
   color: var(--link-hover-color);
 }
 
-.sidebar-module-link {
+a.sidebar-module-link {
   box-sizing: border-box;
   font-size: 14pt;
   line-height: 24px;
   font-family: var(--font-mono);
-  display: block;
+  display: flex;
+  flex-direction: row-reverse;
+  justify-content: space-between;
+  align-items: center;
   width: 100%;
-  padding: 8px 0;
+  padding: 0;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
 }
 
+.sidebar-module-link:hover {
+    text-decoration: none;
+
+    span:hover {
+        color: var(--violet);
+    }
+}
+
+.sidebar-module-link span {
+    display: inline-block;
+    flex-grow: 1;
+}
+
 .sidebar-module-link.active {
   font-weight: bold;
 }
 
+.sidebar-module-link > .entry-toggle {
+    background-color: transparent;
+    appearance: none;
+    border: none;
+    color: transparent;
+    color: rgba(from var(--text-color) r g b / .6);
+    transition: all 80ms linear;
+    text-decoration: none;
+    font-size: 0.6rem;
+    cursor: pointer;
+    padding: 8px 16px;
+    
+    &:hover {
+        color: var(--violet);
+    }
+}
+
+:hover >  .entry-toggle {
+    color: var(--text-color);
+}
+
+.active .entry-toggle {
+    rotate: 90deg;
+}
+
 a,
 a:visited {
   color: var(--link-color);
@@ -473,8 +532,11 @@ pre {
 }
 
 pre>samp {
-  overflow-x: auto;
-  display: block;
+    overflow-x: auto;
+    display: block;
+    scrollbar-color: var(--violet) var(--code-bg);
+    scrollbar-width: thin;
+    scrollbar-gutter: stable;
 }
 
 .hidden {
@@ -490,7 +552,7 @@ pre>samp {
   position: sticky;
   flex-grow: 1;
   box-sizing: border-box;
-  padding-top: 16px;
+  padding-block: 16px;
   background-color: var(--body-bg-color);
   top: 0;
   z-index: 1;
@@ -677,7 +739,7 @@ pre>samp {
     --cyan: hsl(176 84% 70% / 1);
     --blue: hsl(243 43% 80% / 1);
     --violet: #caadfb;
-    --violet-bg: #332944;
+    --violet-bg: hsl(262 25% 15% / 1);
     --magenta: hsl(348 79% 80% / 1);
       --link-hover-color: #fff;
 
@@ -697,7 +759,10 @@ pre>samp {
   }
 }
 
-@media only screen and (max-device-width: 768px) and (orientation: portrait) {
+@media only screen and (max-width: 768px) {
+    :root {
+        --sidebar-width: clamp(280px, 50dvw, 385px);
+    }
     body {
         display: block;
         overflow-y: auto;
@@ -713,6 +778,11 @@ pre>samp {
         transition: all .2s linear;
     }
 
+    .entry-toggle {
+        height: 48px;
+        width: 48px;
+    }
+
     body.sidebar-open #sidebar-nav {
         left: 0;
     }
@@ -720,6 +790,7 @@ pre>samp {
     main {
         display: block;
         margin: 0 16px;
+        --main-content-width: minmax(calc(100% - 32px), 60ch);
     }
 
     :root {
@@ -843,9 +914,7 @@ pre>samp {
     }
 
     .pkg-and-logo {
-        width: 100%;
         padding-block: 4px;
-        align-items: space-between;
     }
 
     .pkg-full-name {

From 249125297ed623f4513f66e244e054301186f5f9 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Mon, 16 Dec 2024 21:15:44 -0800
Subject: [PATCH 04/14] Add missing indent call

---
 crates/compiler/fmt/src/annotation.rs         |  1 +
 ...d_implements_lookalikes.expr.formatted.roc |  6 ++
 ..._and_implements_lookalikes.expr.result-ast | 65 +++++++++++++++++++
 .../where_and_implements_lookalikes.expr.roc  |  3 +
 .../test_syntax/tests/test_snapshots.rs       |  1 +
 5 files changed, 76 insertions(+)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.formatted.roc
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.result-ast
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.roc

diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs
index 0ecef0a553..3caf8345ee 100644
--- a/crates/compiler/fmt/src/annotation.rs
+++ b/crates/compiler/fmt/src/annotation.rs
@@ -410,6 +410,7 @@ fn fmt_ty_ann(
                 buf.spaces(1);
             }
             for (i, has) in implements_clauses.iter().enumerate() {
+                buf.indent(indent);
                 buf.push_str(if i == 0 {
                     roc_parse::keyword::WHERE
                 } else {
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.formatted.roc
new file mode 100644
index 0000000000..672adf6b03
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.formatted.roc
@@ -0,0 +1,6 @@
+(
+    i :
+        a #
+        where w implements I
+    e
+)
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.result-ast
new file mode 100644
index 0000000000..7ee0ef80a6
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.result-ast
@@ -0,0 +1,65 @@
+@0-29 SpaceAfter(
+    ParensAround(
+        Defs(
+            Defs {
+                tags: [
+                    EitherIndex(2147483648),
+                ],
+                regions: [
+                    @1-26,
+                ],
+                space_before: [
+                    Slice { start: 0, length: 0 },
+                ],
+                space_after: [
+                    Slice { start: 0, length: 0 },
+                ],
+                spaces: [],
+                type_defs: [],
+                value_defs: [
+                    Annotation(
+                        @1-2 Identifier {
+                            ident: "i",
+                        },
+                        @3-26 Where(
+                            @3-4 SpaceAfter(
+                                BoundVariable(
+                                    "a",
+                                ),
+                                [
+                                    LineComment(
+                                        "",
+                                    ),
+                                ],
+                            ),
+                            [
+                                @13-26 ImplementsClause {
+                                    var: @13-14 "w",
+                                    abilities: [
+                                        @25-26 Apply(
+                                            "",
+                                            "I",
+                                            [],
+                                        ),
+                                    ],
+                                },
+                            ],
+                        ),
+                    ),
+                ],
+            },
+            @27-28 SpaceBefore(
+                Var {
+                    module_name: "",
+                    ident: "e",
+                },
+                [
+                    Newline,
+                ],
+            ),
+        ),
+    ),
+    [
+        Newline,
+    ],
+)
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.roc
new file mode 100644
index 0000000000..aea6540354
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_and_implements_lookalikes.expr.roc
@@ -0,0 +1,3 @@
+(i:a#
+  wherew implementsI
+e)
diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs
index 2cc131ba92..2f5c1025d0 100644
--- a/crates/compiler/test_syntax/tests/test_snapshots.rs
+++ b/crates/compiler/test_syntax/tests/test_snapshots.rs
@@ -744,6 +744,7 @@ mod test_snapshots {
         pass/when_with_records.expr,
         pass/when_with_tuple_in_record.expr,
         pass/when_with_tuples.expr,
+        pass/where_and_implements_lookalikes.expr,
         pass/where_clause_function.expr,
         pass/where_clause_multiple_bound_abilities.expr,
         pass/where_clause_multiple_has.expr,

From ad1e3369c51ef578e86e66028e61ee31e212dd85 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Mon, 16 Dec 2024 21:42:16 -0800
Subject: [PATCH 05/14] Disallow expect! as an identifier

---
 crates/compiler/parse/src/keyword.rs          |  3 +-
 ..._record_assign_expect_bang.expr.result-ast |  1 +
 .../empty_record_assign_expect_bang.expr.roc  |  0
 ...ted_when_expect_binop_when.expr.result-ast |  1 +
 .../nested_when_expect_binop_when.expr.roc    |  4 ++
 ...cord_assign_expect_bang.expr.formatted.roc |  2 -
 ..._record_assign_expect_bang.expr.result-ast | 51 -------------------
 .../test_syntax/tests/test_snapshots.rs       |  3 +-
 8 files changed, 10 insertions(+), 55 deletions(-)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/fail/empty_record_assign_expect_bang.expr.result-ast
 rename crates/compiler/test_syntax/tests/snapshots/{pass => fail}/empty_record_assign_expect_bang.expr.roc (100%)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.result-ast
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.roc
 delete mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.formatted.roc
 delete mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.result-ast

diff --git a/crates/compiler/parse/src/keyword.rs b/crates/compiler/parse/src/keyword.rs
index ff730a15c0..125a38486e 100644
--- a/crates/compiler/parse/src/keyword.rs
+++ b/crates/compiler/parse/src/keyword.rs
@@ -21,6 +21,7 @@ pub const WHERE: &str = "where";
 // These keywords are valid in headers
 pub const PLATFORM: &str = "platform";
 
-pub const KEYWORDS: [&str; 11] = [
+pub const KEYWORDS: [&str; 12] = [
     IF, THEN, ELSE, WHEN, AS, IS, DBG, IMPORT, EXPECT, RETURN, CRASH,
+    "expect!", // not itself a keyword, but it's problematic if we allow an identifier like this!
 ];
diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/empty_record_assign_expect_bang.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/fail/empty_record_assign_expect_bang.expr.result-ast
new file mode 100644
index 0000000000..8357240265
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/fail/empty_record_assign_expect_bang.expr.result-ast
@@ -0,0 +1 @@
+Expr(Start(@0), @0)
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/empty_record_assign_expect_bang.expr.roc
similarity index 100%
rename from crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.roc
rename to crates/compiler/test_syntax/tests/snapshots/fail/empty_record_assign_expect_bang.expr.roc
diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.result-ast
new file mode 100644
index 0000000000..7ba6f3488a
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.result-ast
@@ -0,0 +1 @@
+Expr(When(Branch(Start(@13), @13), @0), @0)
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.roc
new file mode 100644
index 0000000000..fa16c01db1
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/fail/nested_when_expect_binop_when.expr.roc
@@ -0,0 +1,4 @@
+when s
+is
+z->expect!%when s
+is z->q
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.formatted.roc
deleted file mode 100644
index 0693e6e9f3..0000000000
--- a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.formatted.roc
+++ /dev/null
@@ -1,2 +0,0 @@
-{} = expect! w
-0
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.result-ast
deleted file mode 100644
index 6f75e9a028..0000000000
--- a/crates/compiler/test_syntax/tests/snapshots/pass/empty_record_assign_expect_bang.expr.result-ast
+++ /dev/null
@@ -1,51 +0,0 @@
-@0-13 SpaceAfter(
-    Defs(
-        Defs {
-            tags: [
-                EitherIndex(2147483648),
-            ],
-            regions: [
-                @0-11,
-            ],
-            space_before: [
-                Slice { start: 0, length: 0 },
-            ],
-            space_after: [
-                Slice { start: 0, length: 0 },
-            ],
-            spaces: [],
-            type_defs: [],
-            value_defs: [
-                Body(
-                    @0-2 RecordDestructure(
-                        [],
-                    ),
-                    @3-11 Apply(
-                        @3-10 Var {
-                            module_name: "",
-                            ident: "expect!",
-                        },
-                        [
-                            @10-11 Var {
-                                module_name: "",
-                                ident: "w",
-                            },
-                        ],
-                        Space,
-                    ),
-                ),
-            ],
-        },
-        @12-13 SpaceBefore(
-            Num(
-                "0",
-            ),
-            [
-                Newline,
-            ],
-        ),
-    ),
-    [
-        Newline,
-    ],
-)
diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs
index 2f5c1025d0..3218b09d5e 100644
--- a/crates/compiler/test_syntax/tests/test_snapshots.rs
+++ b/crates/compiler/test_syntax/tests/test_snapshots.rs
@@ -196,6 +196,7 @@ mod test_snapshots {
         fail/double_plus.expr,
         fail/elm_function_syntax.expr,
         fail/empty_or_pattern.expr,
+        fail/empty_record_assign_expect_bang.expr,
         fail/empty_return.expr,
         fail/error_inline_alias_argument_uppercase.expr,
         fail/error_inline_alias_not_an_alias.expr,
@@ -225,6 +226,7 @@ mod test_snapshots {
         fail/module_with_unfinished_params.header,
         fail/multi_no_end.expr,
         fail/nested_tuples_annotation_terrible_perf.expr,
+        fail/nested_when_expect_binop_when.expr,
         fail/newline_before_operator_with_defs.expr,
         fail/opaque_type_def_with_newline.expr,
         fail/pattern_binds_keyword.expr,
@@ -406,7 +408,6 @@ mod test_snapshots {
         pass/empty_platform_header.header,
         pass/empty_record.expr,
         pass/empty_record_assign_backpassing.expr,
-        pass/empty_record_assign_expect_bang.expr,
         pass/empty_record_assign_implements.expr,
         pass/empty_record_assign_return.expr,
         pass/empty_record_assign_tag.expr,

From 769baa9f630ec972a1305ea70080c04e59923455 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Tue, 17 Dec 2024 07:25:10 -0800
Subject: [PATCH 06/14] Add indent call after when's if

---
 crates/compiler/fmt/src/expr.rs               |  1 +
 ...when_comment_bbefore_if.expr.formatted.roc |  5 +++
 .../when_comment_bbefore_if.expr.result-ast   | 40 +++++++++++++++++++
 .../pass/when_comment_bbefore_if.expr.roc     |  3 ++
 .../test_syntax/tests/test_snapshots.rs       |  1 +
 5 files changed, 50 insertions(+)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.formatted.roc
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.result-ast
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.roc

diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs
index 504a1a43e1..f6088b2309 100644
--- a/crates/compiler/fmt/src/expr.rs
+++ b/crates/compiler/fmt/src/expr.rs
@@ -1616,6 +1616,7 @@ fn fmt_when<'a>(
         }
 
         if let Some(guard_expr) = &branch.guard {
+            buf.indent(indent + INDENT);
             buf.push_str(" if");
             buf.spaces(1);
             guard_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent + INDENT);
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.formatted.roc
new file mode 100644
index 0000000000..b5d9e6ab60
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.formatted.roc
@@ -0,0 +1,5 @@
+when
+    0
+is
+    S #
+     if S -> e
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.result-ast
new file mode 100644
index 0000000000..eec8bfed48
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.result-ast
@@ -0,0 +1,40 @@
+@0-21 SpaceAfter(
+    When(
+        @5-6 SpaceAfter(
+            Num(
+                "0",
+            ),
+            [
+                Newline,
+            ],
+        ),
+        [
+            WhenBranch {
+                patterns: [
+                    @10-11 SpaceAfter(
+                        Tag(
+                            "S",
+                        ),
+                        [
+                            LineComment(
+                                "",
+                            ),
+                        ],
+                    ),
+                ],
+                value: @20-21 Var {
+                    module_name: "",
+                    ident: "e",
+                },
+                guard: Some(
+                    @17-18 Tag(
+                        "S",
+                    ),
+                ),
+            },
+        ],
+    ),
+    [
+        Newline,
+    ],
+)
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.roc
new file mode 100644
index 0000000000..095f9e062d
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/when_comment_bbefore_if.expr.roc
@@ -0,0 +1,3 @@
+when 0
+is S#
+ if S->e
diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs
index 3218b09d5e..551bff7f8f 100644
--- a/crates/compiler/test_syntax/tests/test_snapshots.rs
+++ b/crates/compiler/test_syntax/tests/test_snapshots.rs
@@ -727,6 +727,7 @@ mod test_snapshots {
         pass/var_then.expr,
         pass/var_when.expr,
         pass/when_comment_after_pattern.expr,
+        pass/when_comment_bbefore_if.expr,
         pass/when_if_guard.expr,
         pass/when_in_assignment.expr,
         pass/when_in_binops.expr,

From bab5e654808827dba0296bae4fd018392e3e4338 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Wed, 18 Dec 2024 10:31:16 -0800
Subject: [PATCH 07/14] Fix case of expr in binop that ends in closure, when it
 doesn't start on a new line

---
 crates/compiler/fmt/src/expr.rs               | 17 +++++-
 ..._closure_newlines_binop.expr.formatted.roc |  2 +
 ...ble_closure_newlines_binop.expr.result-ast | 52 +++++++++++++++++++
 .../double_closure_newlines_binop.expr.roc    |  3 ++
 .../test_syntax/tests/test_snapshots.rs       |  1 +
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.formatted.roc
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.result-ast
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.roc

diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs
index f6088b2309..b9f354cab9 100644
--- a/crates/compiler/fmt/src/expr.rs
+++ b/crates/compiler/fmt/src/expr.rs
@@ -1405,8 +1405,12 @@ fn fmt_binops<'a>(
             expr_lift_spaces(Parens::InOperator, buf.text.bump(), &loc_left_side.value);
         format_spaces(buf, lifted_left_side.before, Newlines::Yes, indent);
 
+        buf.indent(indent);
+        let line_indent = buf.cur_line_indent();
+
         let need_parens = matches!(lifted_left_side.item, Expr::BinOps(..))
-            || starts_with_unary_minus(lifted_left_side.item);
+            || starts_with_unary_minus(lifted_left_side.item)
+            || (ends_with_closure(&lifted_left_side.item) && line_indent < indent);
 
         if need_parens {
             fmt_parens(&lifted_left_side.item, buf, indent);
@@ -1451,6 +1455,17 @@ fn fmt_binops<'a>(
     format_spaces(buf, lifted_right_side.after, Newlines::Yes, indent);
 }
 
+fn ends_with_closure(item: &Expr<'_>) -> bool {
+    match item {
+        Expr::Closure(..) => true,
+        Expr::Apply(expr, args, _) => args
+            .last()
+            .map(|a| ends_with_closure(&a.value))
+            .unwrap_or_else(|| ends_with_closure(&expr.value)),
+        _ => false,
+    }
+}
+
 fn starts_with_unary_minus(item: Expr<'_>) -> bool {
     match item {
         Expr::UnaryOp(
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.formatted.roc
new file mode 100644
index 0000000000..87104f1b38
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.formatted.roc
@@ -0,0 +1,2 @@
+\j -> (e \B -> B)
+    > s
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.result-ast
new file mode 100644
index 0000000000..43e6ff407f
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.result-ast
@@ -0,0 +1,52 @@
+@0-16 SpaceAfter(
+    Closure(
+        [
+            @1-2 Identifier {
+                ident: "j",
+            },
+        ],
+        @4-16 BinOps(
+            [
+                (
+                    @4-12 SpaceAfter(
+                        Apply(
+                            @4-5 Var {
+                                module_name: "",
+                                ident: "e",
+                            },
+                            [
+                                @5-12 Closure(
+                                    [
+                                        @6-7 SpaceAfter(
+                                            Tag(
+                                                "B",
+                                            ),
+                                            [
+                                                Newline,
+                                            ],
+                                        ),
+                                    ],
+                                    @11-12 Tag(
+                                        "B",
+                                    ),
+                                ),
+                            ],
+                            Space,
+                        ),
+                        [
+                            Newline,
+                        ],
+                    ),
+                    @14-15 GreaterThan,
+                ),
+            ],
+            @15-16 Var {
+                module_name: "",
+                ident: "s",
+            },
+        ),
+    ),
+    [
+        Newline,
+    ],
+)
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.roc
new file mode 100644
index 0000000000..6def52fb43
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/double_closure_newlines_binop.expr.roc
@@ -0,0 +1,3 @@
+\j->e\B
+ ->B
+ >s
diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs
index 551bff7f8f..074da1119d 100644
--- a/crates/compiler/test_syntax/tests/test_snapshots.rs
+++ b/crates/compiler/test_syntax/tests/test_snapshots.rs
@@ -396,6 +396,7 @@ mod test_snapshots {
         pass/defs_suffixed_middle_extra_indents.moduledefs,
         pass/destructure_tag_assignment.expr,
         pass/docs.expr,
+        pass/double_closure_newlines_binop.expr,
         pass/double_parens_as_in_backpassing_pat.expr,
         pass/double_parens_comment_tuple_pat.expr,
         pass/double_space_before.expr,

From 7ba51356021570da66a7c3831779ca40ec8c6d18 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Wed, 18 Dec 2024 10:35:18 -0800
Subject: [PATCH 08/14] Fix as in apply type

---
 crates/compiler/fmt/src/annotation.rs         |  4 +-
 ..._parens_as_parens_h_ann.expr.formatted.roc |  2 +
 .../h_parens_as_parens_h_ann.expr.result-ast  | 62 +++++++++++++++++++
 .../pass/h_parens_as_parens_h_ann.expr.roc    |  2 +
 .../test_syntax/tests/test_snapshots.rs       |  1 +
 5 files changed, 69 insertions(+), 2 deletions(-)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.formatted.roc
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.result-ast
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.roc

diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs
index 3caf8345ee..4dd224cfdf 100644
--- a/crates/compiler/fmt/src/annotation.rs
+++ b/crates/compiler/fmt/src/annotation.rs
@@ -367,13 +367,13 @@ fn fmt_ty_ann(
         }
 
         TypeAnnotation::As(lhs, spaces, TypeHeader { name, vars }) => {
-            let write_parens = parens == Parens::InAsPattern;
+            let write_parens = parens == Parens::InAsPattern || parens == Parens::InApply;
 
+            buf.indent(indent);
             if write_parens {
                 buf.push('(')
             }
 
-            buf.indent(indent);
             let lhs_indent = buf.cur_line_indent();
             lhs.value
                 .format_with_options(buf, Parens::InAsPattern, Newlines::No, indent);
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.formatted.roc
new file mode 100644
index 0000000000..70ec592b74
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.formatted.roc
@@ -0,0 +1,2 @@
+N : A (H as H) H
+I
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.result-ast
new file mode 100644
index 0000000000..d2577b5a2d
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.result-ast
@@ -0,0 +1,62 @@
+@0-16 SpaceAfter(
+    Defs(
+        Defs {
+            tags: [
+                EitherIndex(0),
+            ],
+            regions: [
+                @0-14,
+            ],
+            space_before: [
+                Slice { start: 0, length: 0 },
+            ],
+            space_after: [
+                Slice { start: 0, length: 0 },
+            ],
+            spaces: [],
+            type_defs: [
+                Alias {
+                    header: TypeHeader {
+                        name: @0-1 "N",
+                        vars: [],
+                    },
+                    ann: @2-14 Apply(
+                        "",
+                        "A",
+                        [
+                            @5-0 As(
+                                @5-6 Apply(
+                                    "",
+                                    "H",
+                                    [],
+                                ),
+                                [],
+                                TypeHeader {
+                                    name: @10-11 "H",
+                                    vars: [],
+                                },
+                            ),
+                            @13-14 Apply(
+                                "",
+                                "H",
+                                [],
+                            ),
+                        ],
+                    ),
+                },
+            ],
+            value_defs: [],
+        },
+        @15-16 SpaceBefore(
+            Tag(
+                "I",
+            ),
+            [
+                Newline,
+            ],
+        ),
+    ),
+    [
+        Newline,
+    ],
+)
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.roc
new file mode 100644
index 0000000000..e947cd6608
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/h_parens_as_parens_h_ann.expr.roc
@@ -0,0 +1,2 @@
+N:A((H)as H) H
+I
diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs
index 074da1119d..559d10d508 100644
--- a/crates/compiler/test_syntax/tests/test_snapshots.rs
+++ b/crates/compiler/test_syntax/tests/test_snapshots.rs
@@ -436,6 +436,7 @@ mod test_snapshots {
         pass/function_with_tuple_ext_type.expr,
         pass/function_with_tuple_type.expr,
         pass/h_greater_comment_minus_div.expr,
+        pass/h_parens_as_parens_h_ann.expr,
         pass/highest_float.expr,
         pass/highest_int.expr,
         pass/i_over_not_g.expr,

From 512be85f9a07490919d170fe93a5d37cda673635 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Wed, 18 Dec 2024 10:42:18 -0800
Subject: [PATCH 09/14] Fix parens around as in tag union

---
 crates/compiler/fmt/src/annotation.rs         | 13 +++++
 .../tag_union_ann_with_as.expr.formatted.roc  |  2 +
 .../tag_union_ann_with_as.expr.result-ast     | 56 +++++++++++++++++++
 .../pass/tag_union_ann_with_as.expr.roc       |  2 +
 .../test_syntax/tests/test_snapshots.rs       |  3 +-
 5 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.formatted.roc
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.result-ast
 create mode 100644 crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.roc

diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs
index 4dd224cfdf..e103d5468a 100644
--- a/crates/compiler/fmt/src/annotation.rs
+++ b/crates/compiler/fmt/src/annotation.rs
@@ -1374,6 +1374,19 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
                     inner
                 }
             }
+            TypeAnnotation::As(_left, _sp, _right) => {
+                let lifted = ann_lift_spaces(arena, self);
+                let item = Spaces {
+                    before: lifted.before,
+                    item: Node::TypeAnnotation(lifted.item),
+                    after: lifted.after,
+                };
+                if parens == Parens::InApply || parens == Parens::InAsPattern {
+                    parens_around_node(arena, item)
+                } else {
+                    item
+                }
+            }
             _ => {
                 let lifted = ann_lift_spaces(arena, self);
                 Spaces {
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.formatted.roc
new file mode 100644
index 0000000000..a93d9748dd
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.formatted.roc
@@ -0,0 +1,2 @@
+1 : [N (* as S)]
+_
\ No newline at end of file
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.result-ast
new file mode 100644
index 0000000000..b664da550f
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.result-ast
@@ -0,0 +1,56 @@
+@0-15 SpaceAfter(
+    Defs(
+        Defs {
+            tags: [
+                EitherIndex(2147483648),
+            ],
+            regions: [
+                @0-13,
+            ],
+            space_before: [
+                Slice { start: 0, length: 0 },
+            ],
+            space_after: [
+                Slice { start: 0, length: 0 },
+            ],
+            spaces: [],
+            type_defs: [],
+            value_defs: [
+                Annotation(
+                    @0-1 NumLiteral(
+                        "1",
+                    ),
+                    @2-13 TagUnion {
+                        ext: None,
+                        tags: [
+                            @3-12 Apply {
+                                name: @3-4 "N",
+                                args: [
+                                    @5-0 As(
+                                        @5-6 Wildcard,
+                                        [],
+                                        TypeHeader {
+                                            name: @9-10 "S",
+                                            vars: [],
+                                        },
+                                    ),
+                                ],
+                            },
+                        ],
+                    },
+                ),
+            ],
+        },
+        @14-15 SpaceBefore(
+            Underscore(
+                "",
+            ),
+            [
+                Newline,
+            ],
+        ),
+    ),
+    [
+        Newline,
+    ],
+)
diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.roc
new file mode 100644
index 0000000000..36cf76cf6e
--- /dev/null
+++ b/crates/compiler/test_syntax/tests/snapshots/pass/tag_union_ann_with_as.expr.roc
@@ -0,0 +1,2 @@
+1:[N(*as(S))]
+_
diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs
index 559d10d508..4ef013174e 100644
--- a/crates/compiler/test_syntax/tests/test_snapshots.rs
+++ b/crates/compiler/test_syntax/tests/test_snapshots.rs
@@ -684,6 +684,7 @@ mod test_snapshots {
         pass/tag_destructure_bang.expr,
         pass/tag_destructure_bang_no_space.expr,
         pass/tag_pattern.expr,
+        pass/tag_union_ann_with_as.expr,
         pass/ten_times_eleven.expr,
         pass/three_arg_closure.expr,
         pass/triple_paren_pat_ann.expr,
@@ -773,7 +774,7 @@ mod test_snapshots {
                 true
             }
 
-            "parens_newlines_before_as" => {
+            "parens_newlines_before_as" | "tag_union_ann_with_as" => {
                 // Found unbound type variables {66}
                 //  in type alias `Test.IdentId(0)` [] [] : <66>
                 // Location: crates/compiler/can/src/scope.rs:541:13

From a0f828fa57eb6f3978cc3592ebfcd910f226c803 Mon Sep 17 00:00:00 2001
From: Joshua Warner 
Date: Wed, 18 Dec 2024 10:49:44 -0800
Subject: [PATCH 10/14] Don't minimize malformed parses by default

---
 crates/compiler/test_syntax/src/minimize.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/crates/compiler/test_syntax/src/minimize.rs b/crates/compiler/test_syntax/src/minimize.rs
index bbf8bbc0d2..e2b121799c 100644
--- a/crates/compiler/test_syntax/src/minimize.rs
+++ b/crates/compiler/test_syntax/src/minimize.rs
@@ -112,7 +112,11 @@ fn round_trip_once(input: Input<'_>, options: Options) -> Option {
     };
 
     if actual.is_malformed() {
-        return Some("Initial parse is malformed".to_string());
+        if options.minimize_initial_parse_error {
+            return Some("Initial parse is malformed".to_string());
+        } else {
+            return None;
+        }
     }
 
     let output = actual.format();

From a58b1013e756749da5c35431efde834a70a29717 Mon Sep 17 00:00:00 2001
From: Timon 
Date: Mon, 23 Dec 2024 14:32:32 +0100
Subject: [PATCH 11/14] added devcontainer (#7404)

* added devcontainer

* clean up

* set versions llvm zig

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>

---------

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
Co-authored-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
---
 .devcontainer/devcontainer.json | 38 +++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 .devcontainer/devcontainer.json

diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..3ad6cc5ec9
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,38 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/rust
+{
+	"name": "Rust",
+	// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
+	"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
+
+	// Use 'mounts' to make the cargo cache persistent in a Docker Volume.
+	// "mounts": [
+	// 	{
+	// 		"source": "devcontainer-cargo-cache-${devcontainerId}",
+	// 		"target": "/usr/local/cargo",
+	// 		"type": "volume"
+	// 	}
+	// ]
+
+	// Features to add to the dev container. More info: https://containers.dev/features.
+	"features": {
+		"ghcr.io/devcontainers-contrib/features/zig:1": {
+			"version": "0.13.0"
+		},
+		"ghcr.io/devcontainers-community/features/llvm:3": {
+			"version": 18
+		}
+	},
+	// Use 'forwardPorts' to make a list of ports inside the container available locally.
+	// "forwardPorts": [],
+
+	// Use 'postCreateCommand' to run commands after the container is created.
+	// "postCreateCommand": "rustc --version",
+	"onCreateCommand": "sudo apt-get update && sudo apt-get install -y pkg-config libz-dev libzstd-dev valgrind"  
+
+	// Configure tool-specific properties.
+	// "customizations": {},
+
+	// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
+	// "remoteUser": "root"
+}

From 7daa008a9a9c9ae147438b1560217a19c7192d6b Mon Sep 17 00:00:00 2001
From: Jared Ramirez 
Date: Fri, 20 Dec 2024 16:00:16 -0800
Subject: [PATCH 12/14] Add Num.fromBool

---
 crates/compiler/builtins/roc/Num.roc          |  14 ++
 crates/compiler/module/src/symbol.rs          |   1 +
 crates/compiler/test_gen/src/gen_num.rs       |  34 +++
 ...e_in_polymorphic_expression_issue_4717.txt |  12 +-
 .../test_mono/generated/binary_tree_fbip.txt  |   4 +-
 .../generated/call_function_in_empty_list.txt |   8 +-
 .../call_function_in_empty_list_unbound.txt   |   8 +-
 .../generated/capture_void_layout_task.txt    |   8 +-
 ...ose_correct_recursion_var_under_record.txt |   8 +-
 .../generated/choose_i128_layout.txt          |   4 +-
 .../generated/choose_u128_layout.txt          |   4 +-
 .../test_mono/generated/choose_u64_layout.txt |   4 +-
 ...lambda_set_productive_nullable_wrapped.txt |   8 +-
 .../compiler/test_mono/generated/dbg_expr.txt |   8 +-
 .../test_mono/generated/dbg_nested_expr.txt   |   4 +-
 ...unt_for_usage_after_early_return_in_if.txt |   8 +-
 crates/compiler/test_mono/generated/dict.txt  |   4 +-
 .../generated/empty_list_of_function_type.txt |   4 +-
 .../encode_derived_nested_record_string.txt   |  18 +-
 ...encode_derived_record_one_field_string.txt |  18 +-
 ...ncode_derived_record_two_field_strings.txt |  18 +-
 .../generated/encode_derived_string.txt       |   8 +-
 .../encode_derived_tag_one_field_string.txt   |  18 +-
 ...encode_derived_tag_two_payloads_string.txt |  18 +-
 .../test_mono/generated/factorial.txt         |   8 +-
 ...zation_information_in_lambda_set_thunk.txt |   4 +-
 ...n_in_lambda_set_thunk_independent_defs.txt |   4 +-
 ...e_return_joinpoints_in_bool_lambda_set.txt |   4 +-
 ...e_return_joinpoints_in_enum_lambda_set.txt |   4 +-
 ..._return_joinpoints_in_union_lambda_set.txt |   4 +-
 .../generated/inspect_derived_dict.txt        | 230 +++++++++---------
 .../generated/inspect_derived_list.txt        |  12 +-
 .../inspect_derived_nested_record_string.txt  |   8 +-
 .../generated/inspect_derived_record.txt      |  18 +-
 ...nspect_derived_record_one_field_string.txt |   8 +-
 ...spect_derived_record_two_field_strings.txt |   8 +-
 .../inspect_derived_tag_one_field_string.txt  |   8 +-
 ...nspect_derived_tag_two_payloads_string.txt |   8 +-
 .../test_mono/generated/ir_int_add.txt        |   4 +-
 .../compiler/test_mono/generated/ir_plus.txt  |   4 +-
 .../compiler/test_mono/generated/ir_round.txt |   4 +-
 .../test_mono/generated/ir_two_defs.txt       |   4 +-
 .../test_mono/generated/ir_when_idiv.txt      |  28 +--
 .../test_mono/generated/ir_when_just.txt      |   4 +-
 ...cialize_errors_behind_unified_branches.txt |   4 +-
 .../test_mono/generated/issue_4770.txt        |  22 +-
 .../test_mono/generated/issue_6196.txt        |   4 +-
 .../lambda_capture_niche_u8_vs_u64.txt        |   8 +-
 ...set_with_imported_toplevels_issue_4733.txt |   8 +-
 ...ure_with_multiple_recursive_structures.txt |   8 +-
 .../generated/linked_list_filter.txt          |  12 +-
 .../test_mono/generated/linked_list_map.txt   |   4 +-
 .../generated/list_cannot_update_inplace.txt  |   8 +-
 .../compiler/test_mono/generated/list_get.txt |   4 +-
 .../compiler/test_mono/generated/list_len.txt |   4 +-
 .../generated/list_map_closure_borrows.txt    |   8 +-
 .../generated/list_map_closure_owns.txt       |   8 +-
 ...ist_map_take_capturing_or_noncapturing.txt |  14 +-
 .../generated/list_pass_to_function.txt       |   4 +-
 .../test_mono/generated/list_sort_asc.txt     |   4 +-
 .../generated/multiline_record_pattern.txt    |   4 +-
 .../nested_optional_field_with_binary_op.txt  |   4 +-
 .../generated/nested_pattern_match.txt        |   4 +-
 .../num_width_gt_u8_layout_as_float.txt       |   4 +-
 .../opaque_as_pattern_in_closure_arg.txt      |   4 +-
 .../optional_field_with_binary_op.txt         |   4 +-
 .../test_mono/generated/optional_when.txt     |   4 +-
 .../test_mono/generated/pizza_dbg.txt         |   8 +-
 .../test_mono/generated/quicksort_help.txt    |  12 +-
 .../test_mono/generated/quicksort_swap.txt    |   4 +-
 .../test_mono/generated/rb_tree_fbip.txt      |   8 +-
 .../record_as_pattern_in_closure_arg.txt      |   4 +-
 ...optional_field_function_no_use_default.txt |   4 +-
 ...rd_optional_field_function_use_default.txt |   4 +-
 ...cord_optional_field_let_no_use_default.txt |   4 +-
 .../record_optional_field_let_use_default.txt |   4 +-
 .../test_mono/generated/record_update.txt     |   4 +-
 .../recursive_call_capturing_function.txt     |   4 +-
 ...function_and_union_with_inference_hole.txt |   8 +-
 ..._set_resolved_only_upon_specialization.txt |   8 +-
 .../generated/recursively_build_effect.txt    |   4 +-
 .../compiler/test_mono/generated/rigids.txt   |   4 +-
 .../generated/specialize_after_match.txt      |   8 +-
 .../generated/specialize_closures.txt         |   8 +-
 .../generated/specialize_lowlevel.txt         |   8 +-
 .../generated/tail_call_elimination.txt       |   8 +-
 ...not_duplicate_identical_concrete_types.txt |  18 +-
 ...types_without_unification_of_unifiable.txt |  18 +-
 .../weakening_avoids_overspecialization.txt   |  12 +-
 ...s_in_compiled_decision_tree_issue_5176.txt |   4 +-
 .../test_mono/generated/when_nested_maybe.txt |   4 +-
 .../test_mono/generated/when_on_record.txt    |   4 +-
 .../generated/when_on_two_values.txt          |   4 +-
 93 files changed, 500 insertions(+), 451 deletions(-)

diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc
index a48abf6182..110e4581bb 100644
--- a/crates/compiler/builtins/roc/Num.roc
+++ b/crates/compiler/builtins/roc/Num.roc
@@ -155,6 +155,7 @@ module [
     f64ToParts,
     f32FromParts,
     f64FromParts,
+    fromBool,
     nanF32,
     nanF64,
     infinityF32,
@@ -1458,6 +1459,18 @@ f32FromParts : { sign : Bool, exponent : U8, fraction : U32 } -> F32
 ## The exponent should not be bigger than 0x07FF, any bigger value will be truncated.
 f64FromParts : { sign : Bool, exponent : U16, fraction : U64 } -> F64
 
+## Convert a `Bool` to a `Num`
+## ```roc
+## expect (Num.fromBool Bool.true) == 1
+## expect (Num.fromBool Bool.false) == 0
+## ```
+fromBool : Bool -> Num *
+fromBool = \bool ->
+    if bool then
+        1
+    else
+        0
+
 ## The value for not-a-number for a [F32] according to the IEEE 754 standard.
 nanF32 : F32
 nanF32 = 0.0f32 / 0.0
@@ -1473,3 +1486,4 @@ infinityF32 = 1.0f32 / 0.0
 ## The value for infinity for a [F64] according to the IEEE 754 standard.
 infinityF64 : F64
 infinityF64 = 1.0f64 / 0.0
+
diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs
index 47a2e5f8e2..87ebf52006 100644
--- a/crates/compiler/module/src/symbol.rs
+++ b/crates/compiler/module/src/symbol.rs
@@ -1349,6 +1349,7 @@ define_builtins! {
         166 NUM_NAN_F64: "nanF64"
         167 NUM_INFINITY_F32: "infinityF32"
         168 NUM_INFINITY_F64: "infinityF64"
+        169 NUM_FROM_BOOL: "fromBool"
     }
     4 BOOL: "Bool" => {
         0 BOOL_BOOL: "Bool" exposed_type=true // the Bool.Bool type alias
diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs
index 5977efcd0e..b3d50dd07d 100644
--- a/crates/compiler/test_gen/src/gen_num.rs
+++ b/crates/compiler/test_gen/src/gen_num.rs
@@ -4084,6 +4084,40 @@ fn f64_from_parts() {
     );
 }
 
+#[test]
+#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
+fn from_bool_true() {
+    assert_evals_to!(
+        indoc!(
+            r"
+            bool : Bool
+            bool = Bool.true
+
+            Num.fromBool bool
+            "
+        ),
+        1,
+        u64
+    );
+}
+
+#[test]
+#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
+fn from_bool_false() {
+    assert_evals_to!(
+        indoc!(
+            r"
+            bool : Bool
+            bool = Bool.false
+
+            Num.fromBool bool
+            "
+        ),
+        0,
+        u64
+    );
+}
+
 #[test]
 #[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
 fn nan_f32() {
diff --git a/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt b/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt
index 86af90ed21..7f6c0075b9 100644
--- a/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt
+++ b/crates/compiler/test_mono/generated/anonymous_closure_in_polymorphic_expression_issue_4717.txt
@@ -79,16 +79,16 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
     jump List.679 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.77 (#Attr.2, #Attr.3):
-    let Num.282 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.1 (Test.2):
     let Test.13 : U64 = 0i64;
diff --git a/crates/compiler/test_mono/generated/binary_tree_fbip.txt b/crates/compiler/test_mono/generated/binary_tree_fbip.txt
index 28940afe84..ac3783701f 100644
--- a/crates/compiler/test_mono/generated/binary_tree_fbip.txt
+++ b/crates/compiler/test_mono/generated/binary_tree_fbip.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.4 (Test.27):
     let Test.39 : [C [, C *self *self] *self, ] = TagId(0) ;
diff --git a/crates/compiler/test_mono/generated/call_function_in_empty_list.txt b/crates/compiler/test_mono/generated/call_function_in_empty_list.txt
index 6a1efe1732..1404c63922 100644
--- a/crates/compiler/test_mono/generated/call_function_in_empty_list.txt
+++ b/crates/compiler/test_mono/generated/call_function_in_empty_list.txt
@@ -48,12 +48,12 @@ procedure List.71 (#Attr.2, #Attr.3):
     ret List.677;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.2 (Test.3):
     let Test.7 : {} = Struct {};
diff --git a/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt b/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt
index 3e219530da..82145c34d4 100644
--- a/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt
+++ b/crates/compiler/test_mono/generated/call_function_in_empty_list_unbound.txt
@@ -48,12 +48,12 @@ procedure List.71 (#Attr.2, #Attr.3):
     ret List.677;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.2 (Test.3):
     let Test.7 : {} = Struct {};
diff --git a/crates/compiler/test_mono/generated/capture_void_layout_task.txt b/crates/compiler/test_mono/generated/capture_void_layout_task.txt
index 0487b5e2cf..61e80faf52 100644
--- a/crates/compiler/test_mono/generated/capture_void_layout_task.txt
+++ b/crates/compiler/test_mono/generated/capture_void_layout_task.txt
@@ -29,12 +29,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.10 (Test.69, #Attr.12):
     let Test.72 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;
diff --git a/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt b/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt
index 75323ee1c0..b23094330f 100644
--- a/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt
+++ b/crates/compiler/test_mono/generated/choose_correct_recursion_var_under_record.txt
@@ -90,12 +90,12 @@ procedure List.9 (List.391):
         ret List.661;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Result.5 (Result.14, Result.15):
     let Result.63 : U8 = 1i64;
diff --git a/crates/compiler/test_mono/generated/choose_i128_layout.txt b/crates/compiler/test_mono/generated/choose_i128_layout.txt
index 1fb244b30f..21b5e7e5c8 100644
--- a/crates/compiler/test_mono/generated/choose_i128_layout.txt
+++ b/crates/compiler/test_mono/generated/choose_i128_layout.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.0 ():
     let Test.6 : I128 = 18446744073709551616i64;
diff --git a/crates/compiler/test_mono/generated/choose_u128_layout.txt b/crates/compiler/test_mono/generated/choose_u128_layout.txt
index d9d8b8b842..f4f3c45b99 100644
--- a/crates/compiler/test_mono/generated/choose_u128_layout.txt
+++ b/crates/compiler/test_mono/generated/choose_u128_layout.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.2 : U128 = 170141183460469231731687303715884105728u128;
diff --git a/crates/compiler/test_mono/generated/choose_u64_layout.txt b/crates/compiler/test_mono/generated/choose_u64_layout.txt
index 2c0493ca01..d6eb48a810 100644
--- a/crates/compiler/test_mono/generated/choose_u64_layout.txt
+++ b/crates/compiler/test_mono/generated/choose_u64_layout.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.2 : U64 = 9999999999999999999i64;
diff --git a/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt b/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt
index 84df43f8d9..c2faa3cbae 100644
--- a/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt
+++ b/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt
@@ -33,12 +33,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.248 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/dbg_expr.txt b/crates/compiler/test_mono/generated/dbg_expr.txt
index 67a20163c2..e9f1f9b8b2 100644
--- a/crates/compiler/test_mono/generated/dbg_expr.txt
+++ b/crates/compiler/test_mono/generated/dbg_expr.txt
@@ -35,12 +35,12 @@ procedure Inspect.64 (Inspect.302):
     ret Inspect.302;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.96 (#Attr.2):
-    let Num.282 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.282;
+    let Num.284 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.284;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/dbg_nested_expr.txt b/crates/compiler/test_mono/generated/dbg_nested_expr.txt
index 6a3650ec8a..fd7ac484d6 100644
--- a/crates/compiler/test_mono/generated/dbg_nested_expr.txt
+++ b/crates/compiler/test_mono/generated/dbg_nested_expr.txt
@@ -35,8 +35,8 @@ procedure Inspect.64 (Inspect.302):
     ret Inspect.302;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/dec_refcount_for_usage_after_early_return_in_if.txt b/crates/compiler/test_mono/generated/dec_refcount_for_usage_after_early_return_in_if.txt
index 9486070c43..88f4f16d63 100644
--- a/crates/compiler/test_mono/generated/dec_refcount_for_usage_after_early_return_in_if.txt
+++ b/crates/compiler/test_mono/generated/dec_refcount_for_usage_after_early_return_in_if.txt
@@ -3,12 +3,12 @@ procedure Bool.11 (#Attr.2, #Attr.3):
     ret Bool.24;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.96 (#Attr.2):
-    let Num.282 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.282;
+    let Num.284 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.284;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.247 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/dict.txt b/crates/compiler/test_mono/generated/dict.txt
index b82344ef99..858017977d 100644
--- a/crates/compiler/test_mono/generated/dict.txt
+++ b/crates/compiler/test_mono/generated/dict.txt
@@ -30,8 +30,8 @@ procedure List.6 (#Attr.2):
     ret List.659;
 
 procedure Num.75 (#Attr.2, #Attr.3):
-    let Num.281 : U8 = lowlevel NumSubWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U8 = lowlevel NumSubWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.3 : {} = Struct {};
diff --git a/crates/compiler/test_mono/generated/empty_list_of_function_type.txt b/crates/compiler/test_mono/generated/empty_list_of_function_type.txt
index 3f6643da3b..68a456f58f 100644
--- a/crates/compiler/test_mono/generated/empty_list_of_function_type.txt
+++ b/crates/compiler/test_mono/generated/empty_list_of_function_type.txt
@@ -23,8 +23,8 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.664;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.2 (Test.5):
     let Test.17 : Str = "bar";
diff --git a/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt b/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt
index cbe4549671..a648b584dd 100644
--- a/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt
+++ b/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt
@@ -148,20 +148,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.709;
 
 procedure Num.127 (#Attr.2):
-    let Num.286 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.286;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.288 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.288 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.288;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.290 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.290;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.287 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.287;
+    let Num.289 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.289;
 
 procedure Num.96 (#Attr.2):
-    let Num.285 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.285;
+    let Num.287 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.287;
 
 procedure Str.12 (#Attr.2):
     let Str.258 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt b/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt
index f97f1c8bdc..2602e9bef3 100644
--- a/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt
+++ b/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt
@@ -89,20 +89,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.127 (#Attr.2):
-    let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.282;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.284 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.284;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.12 (#Attr.2):
     let Str.255 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt b/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt
index 311b88e7b2..ca50badd27 100644
--- a/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt
+++ b/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt
@@ -96,20 +96,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.127 (#Attr.2):
-    let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.282;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.284 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.284;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.12 (#Attr.2):
     let Str.255 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/encode_derived_string.txt b/crates/compiler/test_mono/generated/encode_derived_string.txt
index 787973e3a1..ef13c04bd8 100644
--- a/crates/compiler/test_mono/generated/encode_derived_string.txt
+++ b/crates/compiler/test_mono/generated/encode_derived_string.txt
@@ -30,12 +30,12 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.671;
 
 procedure Num.127 (#Attr.2):
-    let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.282;
+    let Num.284 : U8 = lowlevel NumIntCast #Attr.2;
+    ret Num.284;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.12 (#Attr.2):
     let Str.255 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt b/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt
index eaef60877a..516b6c2f7d 100644
--- a/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt
+++ b/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt
@@ -94,20 +94,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.127 (#Attr.2):
-    let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.282;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.284 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.284;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.12 (#Attr.2):
     let Str.255 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt b/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt
index e08ecc31d5..3884deecf1 100644
--- a/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt
+++ b/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt
@@ -97,20 +97,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.127 (#Attr.2):
-    let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.282;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.284 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.284;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.12 (#Attr.2):
     let Str.255 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/factorial.txt b/crates/compiler/test_mono/generated/factorial.txt
index a9655ad62d..35fceaa312 100644
--- a/crates/compiler/test_mono/generated/factorial.txt
+++ b/crates/compiler/test_mono/generated/factorial.txt
@@ -1,10 +1,10 @@
 procedure Num.20 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
     joinpoint Test.7 Test.2 Test.3:
diff --git a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt
index ec22d853c6..243f022c0e 100644
--- a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt
+++ b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.8):
     let Test.3 : I64 = 10i64;
diff --git a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt
index 96fa433e56..7b928918bb 100644
--- a/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt
+++ b/crates/compiler/test_mono/generated/function_specialization_information_in_lambda_set_thunk_independent_defs.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.1 (Test.9):
     let Test.4 : U8 = 10i64;
diff --git a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt
index 0e45e1077e..6ebfb178bf 100644
--- a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt
+++ b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_bool_lambda_set.txt
@@ -3,8 +3,8 @@ procedure Bool.1 ():
     ret Bool.23;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.3 (Test.4):
     ret Test.4;
diff --git a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt
index 8cd25bf390..dc3a6260ea 100644
--- a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt
+++ b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_enum_lambda_set.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.2 (Test.3):
     switch Test.3:
diff --git a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt
index 8e68099151..cfc6080964 100644
--- a/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt
+++ b/crates/compiler/test_mono/generated/inline_return_joinpoints_in_union_lambda_set.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.2 (Test.3, Test.1):
     let Test.18 : Int1 = false;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_dict.txt b/crates/compiler/test_mono/generated/inspect_derived_dict.txt
index cb904e317d..d871c828ff 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_dict.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_dict.txt
@@ -1057,131 +1057,131 @@ procedure List.98 (#Derived_gen.28, #Derived_gen.29, #Derived_gen.30):
     jump List.710 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
 
 procedure Num.131 (#Attr.2):
-    let Num.289 : U32 = lowlevel NumIntCast #Attr.2;
-    ret Num.289;
-
-procedure Num.133 (#Attr.2):
-    let Num.297 : U64 = lowlevel NumIntCast #Attr.2;
-    ret Num.297;
-
-procedure Num.133 (#Attr.2):
-    let Num.346 : U64 = lowlevel NumIntCast #Attr.2;
-    ret Num.346;
-
-procedure Num.133 (#Attr.2):
-    let Num.361 : U64 = lowlevel NumIntCast #Attr.2;
-    ret Num.361;
-
-procedure Num.135 (#Attr.2):
-    let Num.367 : U128 = lowlevel NumIntCast #Attr.2;
-    ret Num.367;
-
-procedure Num.139 (#Attr.2):
-    let Num.315 : Float32 = lowlevel NumToFloatCast #Attr.2;
-    ret Num.315;
-
-procedure Num.148 (Num.225, Num.226):
-    let Num.317 : Int1 = CallByName Num.22 Num.225 Num.226;
-    if Num.317 then
-        ret Num.225;
-    else
-        ret Num.226;
-
-procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.314 : Float32 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.314;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.311 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.311;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.440 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.440;
-
-procedure Num.23 (#Attr.2, #Attr.3):
-    let Num.433 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
-    ret Num.433;
-
-procedure Num.24 (#Attr.2, #Attr.3):
-    let Num.295 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
-    ret Num.295;
-
-procedure Num.24 (#Attr.2, #Attr.3):
-    let Num.436 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
-    ret Num.436;
-
-procedure Num.25 (#Attr.2, #Attr.3):
-    let Num.437 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
-    ret Num.437;
-
-procedure Num.50 (#Attr.2):
-    let Num.313 : U64 = lowlevel NumFloor #Attr.2;
-    ret Num.313;
-
-procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U32 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
-
-procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.439 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.439;
-
-procedure Num.69 (#Attr.2, #Attr.3):
-    let Num.303 : U32 = lowlevel NumBitwiseAnd #Attr.2 #Attr.3;
-    ret Num.303;
-
-procedure Num.70 (#Attr.2, #Attr.3):
-    let Num.344 : U64 = lowlevel NumBitwiseXor #Attr.2 #Attr.3;
-    ret Num.344;
-
-procedure Num.71 (#Attr.2, #Attr.3):
-    let Num.302 : U32 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
-    ret Num.302;
-
-procedure Num.71 (#Attr.2, #Attr.3):
-    let Num.381 : U64 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
-    ret Num.381;
-
-procedure Num.72 (#Attr.2, #Attr.3):
-    let Num.284 : U32 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
-    ret Num.284;
-
-procedure Num.72 (#Attr.2, #Attr.3):
-    let Num.396 : U64 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
-    ret Num.396;
-
-procedure Num.74 (#Attr.2, #Attr.3):
-    let Num.362 : U128 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
-    ret Num.362;
-
-procedure Num.74 (#Attr.2, #Attr.3):
-    let Num.364 : U64 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
-    ret Num.364;
-
-procedure Num.75 (#Attr.2, #Attr.3):
-    let Num.291 : U32 = lowlevel NumSubWrap #Attr.2 #Attr.3;
+    let Num.291 : U32 = lowlevel NumIntCast #Attr.2;
     ret Num.291;
 
-procedure Num.75 (#Attr.2, #Attr.3):
-    let Num.294 : U8 = lowlevel NumSubWrap #Attr.2 #Attr.3;
-    ret Num.294;
+procedure Num.133 (#Attr.2):
+    let Num.299 : U64 = lowlevel NumIntCast #Attr.2;
+    ret Num.299;
+
+procedure Num.133 (#Attr.2):
+    let Num.348 : U64 = lowlevel NumIntCast #Attr.2;
+    ret Num.348;
+
+procedure Num.133 (#Attr.2):
+    let Num.363 : U64 = lowlevel NumIntCast #Attr.2;
+    ret Num.363;
+
+procedure Num.135 (#Attr.2):
+    let Num.369 : U128 = lowlevel NumIntCast #Attr.2;
+    ret Num.369;
+
+procedure Num.139 (#Attr.2):
+    let Num.317 : Float32 = lowlevel NumToFloatCast #Attr.2;
+    ret Num.317;
+
+procedure Num.148 (Num.226, Num.227):
+    let Num.319 : Int1 = CallByName Num.22 Num.226 Num.227;
+    if Num.319 then
+        ret Num.226;
+    else
+        ret Num.227;
+
+procedure Num.21 (#Attr.2, #Attr.3):
+    let Num.316 : Float32 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.316;
+
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.313 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.313;
+
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.442 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.442;
+
+procedure Num.23 (#Attr.2, #Attr.3):
+    let Num.435 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
+    ret Num.435;
+
+procedure Num.24 (#Attr.2, #Attr.3):
+    let Num.297 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
+    ret Num.297;
+
+procedure Num.24 (#Attr.2, #Attr.3):
+    let Num.438 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
+    ret Num.438;
+
+procedure Num.25 (#Attr.2, #Attr.3):
+    let Num.439 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
+    ret Num.439;
+
+procedure Num.50 (#Attr.2):
+    let Num.315 : U64 = lowlevel NumFloor #Attr.2;
+    ret Num.315;
+
+procedure Num.51 (#Attr.2, #Attr.3):
+    let Num.283 : U32 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
+
+procedure Num.51 (#Attr.2, #Attr.3):
+    let Num.441 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.441;
+
+procedure Num.69 (#Attr.2, #Attr.3):
+    let Num.305 : U32 = lowlevel NumBitwiseAnd #Attr.2 #Attr.3;
+    ret Num.305;
+
+procedure Num.70 (#Attr.2, #Attr.3):
+    let Num.346 : U64 = lowlevel NumBitwiseXor #Attr.2 #Attr.3;
+    ret Num.346;
+
+procedure Num.71 (#Attr.2, #Attr.3):
+    let Num.304 : U32 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
+    ret Num.304;
+
+procedure Num.71 (#Attr.2, #Attr.3):
+    let Num.383 : U64 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
+    ret Num.383;
+
+procedure Num.72 (#Attr.2, #Attr.3):
+    let Num.286 : U32 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
+    ret Num.286;
+
+procedure Num.72 (#Attr.2, #Attr.3):
+    let Num.398 : U64 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
+    ret Num.398;
+
+procedure Num.74 (#Attr.2, #Attr.3):
+    let Num.364 : U128 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
+    ret Num.364;
+
+procedure Num.74 (#Attr.2, #Attr.3):
+    let Num.366 : U64 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
+    ret Num.366;
 
 procedure Num.75 (#Attr.2, #Attr.3):
-    let Num.430 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
-    ret Num.430;
+    let Num.293 : U32 = lowlevel NumSubWrap #Attr.2 #Attr.3;
+    ret Num.293;
+
+procedure Num.75 (#Attr.2, #Attr.3):
+    let Num.296 : U8 = lowlevel NumSubWrap #Attr.2 #Attr.3;
+    ret Num.296;
+
+procedure Num.75 (#Attr.2, #Attr.3):
+    let Num.432 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
+    ret Num.432;
 
 procedure Num.78 (#Attr.2, #Attr.3):
-    let Num.365 : U128 = lowlevel NumMulWrap #Attr.2 #Attr.3;
-    ret Num.365;
+    let Num.367 : U128 = lowlevel NumMulWrap #Attr.2 #Attr.3;
+    ret Num.367;
 
 procedure Num.96 (#Attr.2):
-    let Num.310 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.310;
+    let Num.312 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.312;
 
 procedure Num.96 (#Attr.2):
-    let Num.438 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.438;
+    let Num.440 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.440;
 
 procedure Str.12 (#Attr.2):
     let Str.248 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_list.txt b/crates/compiler/test_mono/generated/inspect_derived_list.txt
index 8858de6a1b..d18566e1a5 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_list.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_list.txt
@@ -166,16 +166,16 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.282 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_nested_record_string.txt b/crates/compiler/test_mono/generated/inspect_derived_nested_record_string.txt
index 8ce25e4434..216ee228d0 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_nested_record_string.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_nested_record_string.txt
@@ -284,12 +284,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.681;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.247 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_record.txt b/crates/compiler/test_mono/generated/inspect_derived_record.txt
index bc8d69eaf1..733ac279d0 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_record.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_record.txt
@@ -193,20 +193,20 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
+
+procedure Num.96 (#Attr.2):
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
     ret Num.283;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
-
-procedure Num.96 (#Attr.2):
-    let Num.282 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.282;
+    let Num.284 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.284;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_record_one_field_string.txt b/crates/compiler/test_mono/generated/inspect_derived_record_one_field_string.txt
index c49f518ebc..57ecab3be2 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_record_one_field_string.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_record_one_field_string.txt
@@ -171,12 +171,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_record_two_field_strings.txt b/crates/compiler/test_mono/generated/inspect_derived_record_two_field_strings.txt
index 76bd72a9ed..e22c7a4dfc 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_record_two_field_strings.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_record_two_field_strings.txt
@@ -178,12 +178,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt b/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt
index b7436949b8..feb5992b99 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt
@@ -171,12 +171,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt b/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt
index 15ad95ed93..bf7dbeabbb 100644
--- a/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt
+++ b/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt
@@ -174,12 +174,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/ir_int_add.txt b/crates/compiler/test_mono/generated/ir_int_add.txt
index 8825be31f6..babdfd38d2 100644
--- a/crates/compiler/test_mono/generated/ir_int_add.txt
+++ b/crates/compiler/test_mono/generated/ir_int_add.txt
@@ -3,8 +3,8 @@ procedure List.6 (#Attr.2):
     ret List.659;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.0 ():
     let Test.1 : List I64 = Array [1i64, 2i64];
diff --git a/crates/compiler/test_mono/generated/ir_plus.txt b/crates/compiler/test_mono/generated/ir_plus.txt
index 29a356d102..6a032053dd 100644
--- a/crates/compiler/test_mono/generated/ir_plus.txt
+++ b/crates/compiler/test_mono/generated/ir_plus.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.2 : I64 = 1i64;
diff --git a/crates/compiler/test_mono/generated/ir_round.txt b/crates/compiler/test_mono/generated/ir_round.txt
index 61cef3d782..c8267a9de0 100644
--- a/crates/compiler/test_mono/generated/ir_round.txt
+++ b/crates/compiler/test_mono/generated/ir_round.txt
@@ -1,6 +1,6 @@
 procedure Num.45 (#Attr.2):
-    let Num.281 : I64 = lowlevel NumRound #Attr.2;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumRound #Attr.2;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.2 : Decimal = 3.6dec;
diff --git a/crates/compiler/test_mono/generated/ir_two_defs.txt b/crates/compiler/test_mono/generated/ir_two_defs.txt
index 58534f57dd..f72eeea4c4 100644
--- a/crates/compiler/test_mono/generated/ir_two_defs.txt
+++ b/crates/compiler/test_mono/generated/ir_two_defs.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.1 : I64 = 3i64;
diff --git a/crates/compiler/test_mono/generated/ir_when_idiv.txt b/crates/compiler/test_mono/generated/ir_when_idiv.txt
index 1e1cbccb19..e0dffa7623 100644
--- a/crates/compiler/test_mono/generated/ir_when_idiv.txt
+++ b/crates/compiler/test_mono/generated/ir_when_idiv.txt
@@ -1,22 +1,22 @@
 procedure Num.157 (#Attr.2, #Attr.3):
-    let Num.283 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.30 (#Attr.2):
-    let Num.288 : I64 = 0i64;
-    let Num.287 : Int1 = lowlevel Eq #Attr.2 Num.288;
-    ret Num.287;
+    let Num.290 : I64 = 0i64;
+    let Num.289 : Int1 = lowlevel Eq #Attr.2 Num.290;
+    ret Num.289;
 
-procedure Num.40 (Num.249, Num.250):
-    let Num.284 : Int1 = CallByName Num.30 Num.250;
-    if Num.284 then
-        let Num.286 : {} = Struct {};
-        let Num.285 : [C {}, C I64] = TagId(0) Num.286;
-        ret Num.285;
+procedure Num.40 (Num.250, Num.251):
+    let Num.286 : Int1 = CallByName Num.30 Num.251;
+    if Num.286 then
+        let Num.288 : {} = Struct {};
+        let Num.287 : [C {}, C I64] = TagId(0) Num.288;
+        ret Num.287;
     else
-        let Num.282 : I64 = CallByName Num.157 Num.249 Num.250;
-        let Num.281 : [C {}, C I64] = TagId(1) Num.282;
-        ret Num.281;
+        let Num.284 : I64 = CallByName Num.157 Num.250 Num.251;
+        let Num.283 : [C {}, C I64] = TagId(1) Num.284;
+        ret Num.283;
 
 procedure Test.0 ():
     let Test.8 : I64 = 1000i64;
diff --git a/crates/compiler/test_mono/generated/ir_when_just.txt b/crates/compiler/test_mono/generated/ir_when_just.txt
index b237e4b6ab..9f90d7e293 100644
--- a/crates/compiler/test_mono/generated/ir_when_just.txt
+++ b/crates/compiler/test_mono/generated/ir_when_just.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.10 : I64 = 41i64;
diff --git a/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt b/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt
index 58fbaab489..b829a10792 100644
--- a/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt
+++ b/crates/compiler/test_mono/generated/issue_2583_specialize_errors_behind_unified_branches.txt
@@ -42,8 +42,8 @@ procedure List.9 (List.391):
         ret List.661;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.27 (Str.84):
     let Str.246 : [C Int1, C I64] = CallByName Str.66 Str.84;
diff --git a/crates/compiler/test_mono/generated/issue_4770.txt b/crates/compiler/test_mono/generated/issue_4770.txt
index 272442c9db..c333477a73 100644
--- a/crates/compiler/test_mono/generated/issue_4770.txt
+++ b/crates/compiler/test_mono/generated/issue_4770.txt
@@ -119,24 +119,24 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
     inc #Derived_gen.0;
     jump List.675 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
 
-procedure Num.148 (Num.225, Num.226):
-    let Num.288 : Int1 = CallByName Num.22 Num.225 Num.226;
-    if Num.288 then
-        ret Num.225;
-    else
+procedure Num.148 (Num.226, Num.227):
+    let Num.290 : Int1 = CallByName Num.22 Num.226 Num.227;
+    if Num.290 then
         ret Num.226;
+    else
+        ret Num.227;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.286;
+    let Num.288 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.288;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.284 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Test.1 (#Derived_gen.5):
     joinpoint Test.26 Test.6:
diff --git a/crates/compiler/test_mono/generated/issue_6196.txt b/crates/compiler/test_mono/generated/issue_6196.txt
index cb050be6a7..fa1b1cdfe2 100644
--- a/crates/compiler/test_mono/generated/issue_6196.txt
+++ b/crates/compiler/test_mono/generated/issue_6196.txt
@@ -1,6 +1,6 @@
 procedure Num.20 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
     joinpoint Test.12 Test.2 Test.3:
diff --git a/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt b/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt
index de4d802f41..23be4ae543 100644
--- a/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt
+++ b/crates/compiler/test_mono/generated/lambda_capture_niche_u8_vs_u64.txt
@@ -1,10 +1,10 @@
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Num.96 (#Attr.2):
-    let Num.282 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.282;
+    let Num.284 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.284;
 
 procedure Test.1 (Test.4):
     let Test.13 : [C U8, C U64] = TagId(1) Test.4;
diff --git a/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt b/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt
index de65cbc2da..8d0f07a7e5 100644
--- a/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt
+++ b/crates/compiler/test_mono/generated/lambda_set_with_imported_toplevels_issue_4733.txt
@@ -7,12 +7,12 @@ procedure Bool.2 ():
     ret Bool.24;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.282 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.0 (Test.8):
     let Test.20 : Int1 = CallByName Bool.2;
diff --git a/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt b/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt
index f4369d2965..d685eeb2e0 100644
--- a/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt
+++ b/crates/compiler/test_mono/generated/layout_cache_structure_with_multiple_recursive_structures.txt
@@ -30,12 +30,12 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.669;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.7 (Test.11, Test.12):
     let Test.17 : {[C *self, ], [, C {[C *self, ], *self}]} = Struct {Test.12, Test.11};
diff --git a/crates/compiler/test_mono/generated/linked_list_filter.txt b/crates/compiler/test_mono/generated/linked_list_filter.txt
index 08893f2bcb..659ccd0142 100644
--- a/crates/compiler/test_mono/generated/linked_list_filter.txt
+++ b/crates/compiler/test_mono/generated/linked_list_filter.txt
@@ -1,11 +1,11 @@
-procedure Num.31 (Num.219):
-    let Num.282 : I64 = 2i64;
-    let Num.281 : Int1 = CallByName Num.86 Num.219 Num.282;
-    ret Num.281;
+procedure Num.31 (Num.220):
+    let Num.284 : I64 = 2i64;
+    let Num.283 : Int1 = CallByName Num.86 Num.220 Num.284;
+    ret Num.283;
 
 procedure Num.86 (#Attr.2, #Attr.3):
-    let Num.283 : Int1 = lowlevel NumIsMultipleOf #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : Int1 = lowlevel NumIsMultipleOf #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.2 (#Derived_gen.0, #Derived_gen.1):
     let #Derived_gen.3 : [, C I64 *self] = NullPointer;
diff --git a/crates/compiler/test_mono/generated/linked_list_map.txt b/crates/compiler/test_mono/generated/linked_list_map.txt
index 3a21360c88..3a6f81c737 100644
--- a/crates/compiler/test_mono/generated/linked_list_map.txt
+++ b/crates/compiler/test_mono/generated/linked_list_map.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.10 (Test.11):
     let Test.28 : I64 = 1i64;
diff --git a/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt b/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt
index 674c2431f8..b983046bce 100644
--- a/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt
+++ b/crates/compiler/test_mono/generated/list_cannot_update_inplace.txt
@@ -22,12 +22,12 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
     ret List.666;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.1 ():
     let Test.8 : List I64 = Array [1i64, 2i64, 3i64];
diff --git a/crates/compiler/test_mono/generated/list_get.txt b/crates/compiler/test_mono/generated/list_get.txt
index 550ec2d287..864e5d9aca 100644
--- a/crates/compiler/test_mono/generated/list_get.txt
+++ b/crates/compiler/test_mono/generated/list_get.txt
@@ -19,8 +19,8 @@ procedure List.66 (#Attr.2, #Attr.3):
     ret List.664;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2):
     let Test.6 : List I64 = Array [1i64, 2i64, 3i64];
diff --git a/crates/compiler/test_mono/generated/list_len.txt b/crates/compiler/test_mono/generated/list_len.txt
index 78e2a7dede..10673e6390 100644
--- a/crates/compiler/test_mono/generated/list_len.txt
+++ b/crates/compiler/test_mono/generated/list_len.txt
@@ -7,8 +7,8 @@ procedure List.6 (#Attr.2):
     ret List.660;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.1 : List I64 = Array [1i64, 2i64, 3i64];
diff --git a/crates/compiler/test_mono/generated/list_map_closure_borrows.txt b/crates/compiler/test_mono/generated/list_map_closure_borrows.txt
index 004c78e32c..e64c144098 100644
--- a/crates/compiler/test_mono/generated/list_map_closure_borrows.txt
+++ b/crates/compiler/test_mono/generated/list_map_closure_borrows.txt
@@ -63,12 +63,12 @@ procedure List.71 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Str.16 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrRepeat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/list_map_closure_owns.txt b/crates/compiler/test_mono/generated/list_map_closure_owns.txt
index 5efc2e0d6d..f573a1fb7a 100644
--- a/crates/compiler/test_mono/generated/list_map_closure_owns.txt
+++ b/crates/compiler/test_mono/generated/list_map_closure_owns.txt
@@ -62,12 +62,12 @@ procedure List.71 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.247 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt b/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt
index 982d5a1355..f95dd5a567 100644
--- a/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt
+++ b/crates/compiler/test_mono/generated/list_map_take_capturing_or_noncapturing.txt
@@ -63,16 +63,16 @@ procedure List.71 (#Attr.2, #Attr.3):
     ret List.677;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.283 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.283;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.285 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.285 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
     ret Num.285;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.287 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.287;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.284 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Test.4 (Test.5, #Attr.12):
     let Test.16 : U8 = UnionAtIndex (Id 0) (Index 0) #Attr.12;
diff --git a/crates/compiler/test_mono/generated/list_pass_to_function.txt b/crates/compiler/test_mono/generated/list_pass_to_function.txt
index e899861ea3..fa9abd3283 100644
--- a/crates/compiler/test_mono/generated/list_pass_to_function.txt
+++ b/crates/compiler/test_mono/generated/list_pass_to_function.txt
@@ -22,8 +22,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
     ret List.664;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.2 (Test.3):
     let Test.6 : U64 = 0i64;
diff --git a/crates/compiler/test_mono/generated/list_sort_asc.txt b/crates/compiler/test_mono/generated/list_sort_asc.txt
index 58d4f3302f..2ab763a446 100644
--- a/crates/compiler/test_mono/generated/list_sort_asc.txt
+++ b/crates/compiler/test_mono/generated/list_sort_asc.txt
@@ -8,8 +8,8 @@ procedure List.59 (List.386):
     ret List.659;
 
 procedure Num.46 (#Attr.2, #Attr.3):
-    let Num.281 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.2 : List I64 = Array [4i64, 3i64, 2i64, 1i64];
diff --git a/crates/compiler/test_mono/generated/multiline_record_pattern.txt b/crates/compiler/test_mono/generated/multiline_record_pattern.txt
index baecd19d98..08ebb59dbd 100644
--- a/crates/compiler/test_mono/generated/multiline_record_pattern.txt
+++ b/crates/compiler/test_mono/generated/multiline_record_pattern.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.0 ():
     let Test.7 : I64 = 1i64;
diff --git a/crates/compiler/test_mono/generated/nested_optional_field_with_binary_op.txt b/crates/compiler/test_mono/generated/nested_optional_field_with_binary_op.txt
index 617adedd42..aa064f3c24 100644
--- a/crates/compiler/test_mono/generated/nested_optional_field_with_binary_op.txt
+++ b/crates/compiler/test_mono/generated/nested_optional_field_with_binary_op.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.17 : {} = Struct {};
diff --git a/crates/compiler/test_mono/generated/nested_pattern_match.txt b/crates/compiler/test_mono/generated/nested_pattern_match.txt
index 32875666f6..af25c66f88 100644
--- a/crates/compiler/test_mono/generated/nested_pattern_match.txt
+++ b/crates/compiler/test_mono/generated/nested_pattern_match.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.19 : I64 = 41i64;
diff --git a/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt b/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt
index 936b6203e1..81b89cdce3 100644
--- a/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt
+++ b/crates/compiler/test_mono/generated/num_width_gt_u8_layout_as_float.txt
@@ -1,6 +1,6 @@
 procedure Num.37 (#Attr.2, #Attr.3):
-    let Num.281 : Decimal = lowlevel NumDivFrac #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Decimal = lowlevel NumDivFrac #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.2 : Decimal = 1dec;
diff --git a/crates/compiler/test_mono/generated/opaque_as_pattern_in_closure_arg.txt b/crates/compiler/test_mono/generated/opaque_as_pattern_in_closure_arg.txt
index 834b3ee0f5..20af6c30d9 100644
--- a/crates/compiler/test_mono/generated/opaque_as_pattern_in_closure_arg.txt
+++ b/crates/compiler/test_mono/generated/opaque_as_pattern_in_closure_arg.txt
@@ -1,6 +1,6 @@
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.2 (Test.8):
     let Test.14 : U64 = 2i64;
diff --git a/crates/compiler/test_mono/generated/optional_field_with_binary_op.txt b/crates/compiler/test_mono/generated/optional_field_with_binary_op.txt
index 4e2be037b4..106e39ea31 100644
--- a/crates/compiler/test_mono/generated/optional_field_with_binary_op.txt
+++ b/crates/compiler/test_mono/generated/optional_field_with_binary_op.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.5 : {} = Struct {};
diff --git a/crates/compiler/test_mono/generated/optional_when.txt b/crates/compiler/test_mono/generated/optional_when.txt
index c1ceb98a6e..0ea3774615 100644
--- a/crates/compiler/test_mono/generated/optional_when.txt
+++ b/crates/compiler/test_mono/generated/optional_when.txt
@@ -1,6 +1,6 @@
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.1 (Test.6):
     let Test.21 : Int1 = false;
diff --git a/crates/compiler/test_mono/generated/pizza_dbg.txt b/crates/compiler/test_mono/generated/pizza_dbg.txt
index e2e8cfa2fa..f5c2314062 100644
--- a/crates/compiler/test_mono/generated/pizza_dbg.txt
+++ b/crates/compiler/test_mono/generated/pizza_dbg.txt
@@ -35,12 +35,12 @@ procedure Inspect.64 (Inspect.302):
     ret Inspect.302;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.96 (#Attr.2):
-    let Num.282 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.282;
+    let Num.284 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.284;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.246 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/quicksort_help.txt b/crates/compiler/test_mono/generated/quicksort_help.txt
index 5f2d3e63e8..2b5a06dbda 100644
--- a/crates/compiler/test_mono/generated/quicksort_help.txt
+++ b/crates/compiler/test_mono/generated/quicksort_help.txt
@@ -1,14 +1,14 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.20 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.1 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
     joinpoint Test.12 Test.2 Test.3 Test.4:
diff --git a/crates/compiler/test_mono/generated/quicksort_swap.txt b/crates/compiler/test_mono/generated/quicksort_swap.txt
index 8838750d6b..2d1244e63c 100644
--- a/crates/compiler/test_mono/generated/quicksort_swap.txt
+++ b/crates/compiler/test_mono/generated/quicksort_swap.txt
@@ -38,8 +38,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
     ret List.664;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.1 (Test.2):
     let Test.28 : U64 = 0i64;
diff --git a/crates/compiler/test_mono/generated/rb_tree_fbip.txt b/crates/compiler/test_mono/generated/rb_tree_fbip.txt
index 2bfdeb6006..19b36ee93b 100644
--- a/crates/compiler/test_mono/generated/rb_tree_fbip.txt
+++ b/crates/compiler/test_mono/generated/rb_tree_fbip.txt
@@ -1,10 +1,10 @@
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Num.24 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
     let #Derived_gen.4 : [C *self I64 *self I32 Int1, ] = NullPointer;
diff --git a/crates/compiler/test_mono/generated/record_as_pattern_in_closure_arg.txt b/crates/compiler/test_mono/generated/record_as_pattern_in_closure_arg.txt
index 5d25c983bf..1657693a41 100644
--- a/crates/compiler/test_mono/generated/record_as_pattern_in_closure_arg.txt
+++ b/crates/compiler/test_mono/generated/record_as_pattern_in_closure_arg.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.1 (Test.12):
     let Test.6 : I64 = StructAtIndex 0 Test.12;
diff --git a/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt
index 0bf4a409e4..aa3b390ebd 100644
--- a/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt
+++ b/crates/compiler/test_mono/generated/record_optional_field_function_no_use_default.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.4):
     let Test.2 : I64 = StructAtIndex 0 Test.4;
diff --git a/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt
index 63d2b8e07f..a732324ebe 100644
--- a/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt
+++ b/crates/compiler/test_mono/generated/record_optional_field_function_use_default.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.4):
     let Test.2 : I64 = 10i64;
diff --git a/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt
index f8ee86c57d..558f64dd33 100644
--- a/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt
+++ b/crates/compiler/test_mono/generated/record_optional_field_let_no_use_default.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2):
     let Test.3 : I64 = StructAtIndex 0 Test.2;
diff --git a/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt b/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt
index d877cdf19c..756a9c6bc2 100644
--- a/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt
+++ b/crates/compiler/test_mono/generated/record_optional_field_let_use_default.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2):
     let Test.3 : I64 = 10i64;
diff --git a/crates/compiler/test_mono/generated/record_update.txt b/crates/compiler/test_mono/generated/record_update.txt
index 26ae908df8..e67233c5c7 100644
--- a/crates/compiler/test_mono/generated/record_update.txt
+++ b/crates/compiler/test_mono/generated/record_update.txt
@@ -22,8 +22,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
     ret List.664;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.281 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2):
     let Test.6 : List U64 = StructAtIndex 0 Test.2;
diff --git a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt
index 85f788c9cb..a93fca63c8 100644
--- a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt
+++ b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt
@@ -3,8 +3,8 @@ procedure Bool.2 ():
     ret Bool.23;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2):
     let Test.8 : U32 = 0i64;
diff --git a/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt b/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt
index 989402fda0..c9edc42975 100644
--- a/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt
+++ b/crates/compiler/test_mono/generated/recursive_function_and_union_with_inference_hole.txt
@@ -49,12 +49,12 @@ procedure List.71 (#Attr.2, #Attr.3):
     ret List.677;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.282 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.281 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.2 (Test.5):
     let Test.6 : List [C List *self] = UnionAtIndex (Id 0) (Index 0) Test.5;
diff --git a/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt b/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt
index 06f48f983f..b1bd508121 100644
--- a/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt
+++ b/crates/compiler/test_mono/generated/recursive_lambda_set_resolved_only_upon_specialization.txt
@@ -3,12 +3,12 @@ procedure Bool.11 (#Attr.2, #Attr.3):
     ret Bool.23;
 
 procedure Num.20 (#Attr.2, #Attr.3):
-    let Num.282 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.281 : U8 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U8 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (#Derived_gen.2, #Derived_gen.3):
     joinpoint Test.11 Test.2 Test.3:
diff --git a/crates/compiler/test_mono/generated/recursively_build_effect.txt b/crates/compiler/test_mono/generated/recursively_build_effect.txt
index 16fe61d5a5..391c13c39b 100644
--- a/crates/compiler/test_mono/generated/recursively_build_effect.txt
+++ b/crates/compiler/test_mono/generated/recursively_build_effect.txt
@@ -1,6 +1,6 @@
 procedure Num.20 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Str.3 (#Attr.2, #Attr.3):
     let Str.248 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
diff --git a/crates/compiler/test_mono/generated/rigids.txt b/crates/compiler/test_mono/generated/rigids.txt
index ed27fe5880..867d227cb5 100644
--- a/crates/compiler/test_mono/generated/rigids.txt
+++ b/crates/compiler/test_mono/generated/rigids.txt
@@ -38,8 +38,8 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
     ret List.664;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.283 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.1 (Test.2, Test.3, Test.4):
     let Test.29 : [C {}, C I64] = CallByName List.2 Test.4 Test.3;
diff --git a/crates/compiler/test_mono/generated/specialize_after_match.txt b/crates/compiler/test_mono/generated/specialize_after_match.txt
index 081cbdc840..2feb395e37 100644
--- a/crates/compiler/test_mono/generated/specialize_after_match.txt
+++ b/crates/compiler/test_mono/generated/specialize_after_match.txt
@@ -1,10 +1,10 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.24 (#Attr.2, #Attr.3):
-    let Num.283 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Test.2 (Test.9, Test.10):
     let Test.38 : U8 = 1i64;
diff --git a/crates/compiler/test_mono/generated/specialize_closures.txt b/crates/compiler/test_mono/generated/specialize_closures.txt
index ad9a4917a7..4389567e2b 100644
--- a/crates/compiler/test_mono/generated/specialize_closures.txt
+++ b/crates/compiler/test_mono/generated/specialize_closures.txt
@@ -3,12 +3,12 @@ procedure Bool.2 ():
     ret Bool.24;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2, Test.3):
     let Test.15 : U8 = GetTagId Test.2;
diff --git a/crates/compiler/test_mono/generated/specialize_lowlevel.txt b/crates/compiler/test_mono/generated/specialize_lowlevel.txt
index d160decc95..d260e51acd 100644
--- a/crates/compiler/test_mono/generated/specialize_lowlevel.txt
+++ b/crates/compiler/test_mono/generated/specialize_lowlevel.txt
@@ -3,12 +3,12 @@ procedure Bool.2 ():
     ret Bool.23;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Num.21 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.6 (Test.8, #Attr.12):
     let Test.20 : I64 = UnionAtIndex (Id 0) (Index 0) #Attr.12;
diff --git a/crates/compiler/test_mono/generated/tail_call_elimination.txt b/crates/compiler/test_mono/generated/tail_call_elimination.txt
index a79c088324..f86a668bc7 100644
--- a/crates/compiler/test_mono/generated/tail_call_elimination.txt
+++ b/crates/compiler/test_mono/generated/tail_call_elimination.txt
@@ -1,10 +1,10 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Num.20 (#Attr.2, #Attr.3):
-    let Num.282 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
     joinpoint Test.7 Test.2 Test.3:
diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt
index e5fc4dc70b..01261e4c16 100644
--- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt
+++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt
@@ -83,20 +83,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.683;
 
 procedure Num.127 (#Attr.2):
-    let Num.282 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.282;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.284 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.284;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.96 (#Attr.2):
-    let Num.281 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.281;
+    let Num.283 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.283;
 
 procedure Str.12 (#Attr.2):
     let Str.247 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt
index c181272837..8cb0c39eaf 100644
--- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt
+++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt
@@ -176,20 +176,20 @@ procedure List.8 (#Attr.2, #Attr.3):
     ret List.710;
 
 procedure Num.127 (#Attr.2):
-    let Num.286 : U8 = lowlevel NumIntCast #Attr.2;
-    ret Num.286;
-
-procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.288 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    let Num.288 : U8 = lowlevel NumIntCast #Attr.2;
     ret Num.288;
 
+procedure Num.22 (#Attr.2, #Attr.3):
+    let Num.290 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.290;
+
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.287 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.287;
+    let Num.289 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.289;
 
 procedure Num.96 (#Attr.2):
-    let Num.285 : Str = lowlevel NumToStr #Attr.2;
-    ret Num.285;
+    let Num.287 : Str = lowlevel NumToStr #Attr.2;
+    ret Num.287;
 
 procedure Str.12 (#Attr.2):
     let Str.250 : List U8 = lowlevel StrToUtf8 #Attr.2;
diff --git a/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt b/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt
index 7b072af74e..66b3284078 100644
--- a/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt
+++ b/crates/compiler/test_mono/generated/weakening_avoids_overspecialization.txt
@@ -79,16 +79,16 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
     jump List.679 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
 
 procedure Num.22 (#Attr.2, #Attr.3):
-    let Num.284 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
-    ret Num.284;
+    let Num.286 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
+    ret Num.286;
 
 procedure Num.51 (#Attr.2, #Attr.3):
-    let Num.283 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
-    ret Num.283;
+    let Num.285 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
+    ret Num.285;
 
 procedure Num.77 (#Attr.2, #Attr.3):
-    let Num.282 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
-    ret Num.282;
+    let Num.284 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
+    ret Num.284;
 
 procedure Test.3 (Test.4, Test.12):
     let Test.13 : [C U64, C U64] = TagId(0) Test.4;
diff --git a/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt b/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt
index bdd8a6188c..faccfbc19d 100644
--- a/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt
+++ b/crates/compiler/test_mono/generated/when_guard_appears_multiple_times_in_compiled_decision_tree_issue_5176.txt
@@ -3,8 +3,8 @@ procedure Bool.2 ():
     ret Bool.25;
 
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.1 (Test.2):
     joinpoint Test.12:
diff --git a/crates/compiler/test_mono/generated/when_nested_maybe.txt b/crates/compiler/test_mono/generated/when_nested_maybe.txt
index 32875666f6..af25c66f88 100644
--- a/crates/compiler/test_mono/generated/when_nested_maybe.txt
+++ b/crates/compiler/test_mono/generated/when_nested_maybe.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.19 : I64 = 41i64;
diff --git a/crates/compiler/test_mono/generated/when_on_record.txt b/crates/compiler/test_mono/generated/when_on_record.txt
index 9da4345549..dfb97f9b13 100644
--- a/crates/compiler/test_mono/generated/when_on_record.txt
+++ b/crates/compiler/test_mono/generated/when_on_record.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.5 : I64 = 2i64;
diff --git a/crates/compiler/test_mono/generated/when_on_two_values.txt b/crates/compiler/test_mono/generated/when_on_two_values.txt
index 742cb21af2..c9e6190628 100644
--- a/crates/compiler/test_mono/generated/when_on_two_values.txt
+++ b/crates/compiler/test_mono/generated/when_on_two_values.txt
@@ -1,6 +1,6 @@
 procedure Num.19 (#Attr.2, #Attr.3):
-    let Num.281 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
-    ret Num.281;
+    let Num.283 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
+    ret Num.283;
 
 procedure Test.0 ():
     let Test.15 : I64 = 3i64;

From 2b6eaf48d8cb3bde19c98416bd6696092f1216ac Mon Sep 17 00:00:00 2001
From: Sam Mohr 
Date: Wed, 25 Dec 2024 11:44:24 -0800
Subject: [PATCH 13/14] Add Task.combine

---
 crates/compiler/builtins/roc/Task.roc | 28 +++++++++++++++++++++++++--
 crates/compiler/module/src/symbol.rs  |  7 ++++---
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/crates/compiler/builtins/roc/Task.roc b/crates/compiler/builtins/roc/Task.roc
index 368ee64bd6..40e1a91630 100644
--- a/crates/compiler/builtins/roc/Task.roc
+++ b/crates/compiler/builtins/roc/Task.roc
@@ -11,6 +11,7 @@ module [
     loop,
     fromResult,
     batch,
+    combine,
     sequence,
     forEach,
     result,
@@ -187,8 +188,11 @@ fromResult : Result a b -> Task a b
 fromResult = \res ->
     @Task \{} -> res
 
-## Apply a task to another task applicatively. This can be used with
-## [ok] to build a [Task] that returns a record.
+## Apply a task to another task applicatively.
+##
+## DEPRECATED: Modern record builders use [combine].
+##
+## This can be used with [ok] to build a [Task] that returns a record.
 ##
 ## The following example returns a Record with two fields, `apples` and
 ## `oranges`, each of which is a `List Str`. If it fails it returns the tag
@@ -207,6 +211,26 @@ batch = \current ->
         await next \f ->
             map current f
 
+## Combine the values of two tasks with a custom combining function.
+##
+## This is primarily used with record builders.
+##
+## ```
+## { a, b, c } =
+##     { Task.combine <-
+##         a: Task.ok 123,
+##         b: File.read "file.txt",
+##         c: Http.get "http://api.com/",
+##     }!
+## ```
+combine : Task a err, Task b err, (a, b -> c) -> Task c err
+combine = \@Task leftTask, @Task rightTask, combiner ->
+    @Task \{} ->
+        left = try leftTask {}
+        right = try rightTask {}
+
+        Ok (combiner left right)
+
 ## Apply each task in a list sequentially, and return a list of the resulting values.
 ## Each task will be awaited before beginning the next task.
 ##
diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs
index 87ebf52006..8be0f15cdd 100644
--- a/crates/compiler/module/src/symbol.rs
+++ b/crates/compiler/module/src/symbol.rs
@@ -1730,9 +1730,10 @@ define_builtins! {
         9 TASK_MAP_ERR: "mapErr"
         10 TASK_FROM_RESULT: "fromResult"
         11 TASK_BATCH: "batch"
-        12 TASK_SEQUENCE: "sequence"
-        13 TASK_FOR_EACH: "forEach"
-        14 TASK_RESULT: "result"
+        12 TASK_COMBINE: "combine"
+        13 TASK_SEQUENCE: "sequence"
+        14 TASK_FOR_EACH: "forEach"
+        15 TASK_RESULT: "result"
     }
 
     num_modules: 16 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)

From 87fb90660f8e3e17db06011a0ac7981732588d1a Mon Sep 17 00:00:00 2001
From: Sam Mohr 
Date: Wed, 25 Dec 2024 12:30:43 -0800
Subject: [PATCH 14/14] Remove broken docs example for Task.batch

---
 crates/compiler/builtins/roc/Task.roc | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/crates/compiler/builtins/roc/Task.roc b/crates/compiler/builtins/roc/Task.roc
index 40e1a91630..3f03f23d69 100644
--- a/crates/compiler/builtins/roc/Task.roc
+++ b/crates/compiler/builtins/roc/Task.roc
@@ -191,20 +191,6 @@ fromResult = \res ->
 ## Apply a task to another task applicatively.
 ##
 ## DEPRECATED: Modern record builders use [combine].
-##
-## This can be used with [ok] to build a [Task] that returns a record.
-##
-## The following example returns a Record with two fields, `apples` and
-## `oranges`, each of which is a `List Str`. If it fails it returns the tag
-## `NoFruitAvailable`.
-##
-## ```
-## getFruitBasket : Task { apples : List Str, oranges : List Str } [NoFruitAvailable]
-## getFruitBasket = Task.ok {
-##     apples: <- getFruit Apples |> Task.batch,
-##     oranges: <- getFruit Oranges |> Task.batch,
-## }
-## ```
 batch : Task a c -> (Task (a -> b) c -> Task b c)
 batch = \current ->
     \next ->