Repository: gleam-lang/gleam (rust)

Issue:
JavaScript codegen bug with `assert`
When compiling an `assert` statement on the JavaScript target, invalid code seems to be generated in a very specific case. For example:
```gleam
assert 0 |> int.add(1) == 1
```
Compiles and runs as intended, however:
```gleam
assert 1 == 0 |> int.add(1)
```
Generates invalid code.

This only seems to happen for `assert` statements, as replacing the `assert` keyword with `let _ =` runs fine.

Pull request:
Fix JS bug with pipes and `assert`
Fixes #4643

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e35786ff1..19934920a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Changelog
 
+## Unreleased
+
+### Bug fixes
+
+- Fixed a bug where using a pipe operator on the right-hand side of an `assert`
+  statement would generate invalid code on the JavaScript target.
+  ([Surya Rose](https://github.com/GearsDatapacks))
+
 ## v1.11.0-rc2 - 2025-05-29
 
 ### Compiler
diff --git a/compiler-core/src/javascript/expression.rs b/compiler-core/src/javascript/expression.rs
index ff3e345e1..58b44a4fa 100644
--- a/compiler-core/src/javascript/expression.rs
+++ b/compiler-core/src/javascript/expression.rs
@@ -1012,8 +1012,10 @@ impl<'module, 'a> Generator<'module, 'a> {
                     _ => {}
                 }
 
-                let left_document = self.assign_to_variable(left)?;
-                let right_document = self.not_in_tail_position(Some(Ordering::Strict), |this| {
+                let left_document = self.not_in_tail_position(Some(Ordering::Loose), |this| {
+                    this.assign_to_variable(left)
+                })?;
+                let right_document = self.not_in_tail_position(Some(Ordering::Loose), |this| {
                     this.assign_to_variable(right)
                 })?;
 


Test patch:
diff --git a/compiler-core/src/javascript/tests/assert.rs b/compiler-core/src/javascript/tests/assert.rs
index 808c8a410..bc0df4044 100644
--- a/compiler-core/src/javascript/tests/assert.rs
+++ b/compiler-core/src/javascript/tests/assert.rs
@@ -173,3 +173,17 @@ pub fn go(x: Nil) {
 "#
     );
 }
+
+// https://github.com/gleam-lang/gleam/issues/4643
+#[test]
+fn assert_with_pipe_on_right() {
+    assert_js!(
+        "
+fn add(a, b) { a + b }
+
+pub fn main() {
+  assert 3 == 1 |> add(2)
+}
+"
+    );
+}
diff --git a/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__assert__assert_with_pipe_on_right.snap b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__assert__assert_with_pipe_on_right.snap
new file mode 100644
index 000000000..1307e493f
--- /dev/null
+++ b/compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__assert__assert_with_pipe_on_right.snap
@@ -0,0 +1,49 @@
+---
+source: compiler-core/src/javascript/tests/assert.rs
+expression: "\nfn add(a, b) { a + b }\n\npub fn main() {\n  assert 3 == 1 |> add(2)\n}\n"
+---
+----- SOURCE CODE
+
+fn add(a, b) { a + b }
+
+pub fn main() {
+  assert 3 == 1 |> add(2)
+}
+
+
+----- COMPILED JAVASCRIPT
+import { makeError } from "../gleam.mjs";
+
+const FILEPATH = "src/module.gleam";
+
+function add(a, b) {
+  return a + b;
+}
+
+export function main() {
+  let _block;
+  let $ = 3;
+  let _pipe = 1;
+  _block = add(_pipe, 2);
+  let $1 = _block;
+  if (!($ === $1)) {
+    throw makeError(
+      "assert",
+      FILEPATH,
+      "my/mod",
+      5,
+      "main",
+      "Assertion failed.",
+      {
+        kind: "binary_operator",
+        operator: "==",
+        left: { kind: "literal", value: $, start: 50, end: 51 },
+        right: { kind: "expression", value: $1, start: 55, end: 66 },
+        start: 43,
+        end: 66,
+        expression_start: 50
+      }
+    )
+  }
+  return undefined;
+}