From 94aa5c91b295183133f75df0268c07bf711a2dce Mon Sep 17 00:00:00 2001 From: Cam Pedersen Date: Tue, 14 Jul 2026 09:54:15 -0400 Subject: [PATCH] EIR VM: assert-eq uses structural equality, not handle identity [assert-eq {:a 1} {:a 1}] failed on the EIR VM because Built::AssertEq compared raw Val handles; two separately-allocated but structurally equal heap values (maps, vecs, non-interned strings) never matched. Route it through the same val_eq that = already uses, and add a backend-parity regression test. Co-Authored-By: Claude Fable 5 --- crates/loon-lang/src/eir/vm.rs | 2 +- crates/loon-lang/tests/backend_parity.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/loon-lang/src/eir/vm.rs b/crates/loon-lang/src/eir/vm.rs index 02ee237..ee32bdd 100644 --- a/crates/loon-lang/src/eir/vm.rs +++ b/crates/loon-lang/src/eir/vm.rs @@ -2608,7 +2608,7 @@ impl Vm { // [assert-eq actual expected] → Unit or panic let actual = args.first().copied().unwrap_or(Val::UNIT); let expected = args.get(1).copied().unwrap_or(Val::UNIT); - if actual == expected { + if self.val_eq(actual, expected) { Ok(Val::UNIT) } else { let actual_s = self.val_to_string(actual); diff --git a/crates/loon-lang/tests/backend_parity.rs b/crates/loon-lang/tests/backend_parity.rs index 8def2e5..1cd2322 100644 --- a/crates/loon-lang/tests/backend_parity.rs +++ b/crates/loon-lang/tests/backend_parity.rs @@ -216,6 +216,13 @@ const CORPUS: &[(&str, &str)] = &[ "map-eq-order-independent", "[fn main [] [println [= {:a 1 :b 2} {:b 2 :a 1}]]]", ), + ( + // assert-eq must use the same structural equality as `=` — the EIR VM + // used to compare raw heap handles, so two separately-allocated but + // equal maps failed the assertion. + "assert-eq-structural", + "[fn main [] [assert-eq {:a 1 :b \"x\"} {:b \"x\" :a 1}] [println \"ok\"]]", + ), // map destructuring in let: `{name name}` shorthand binds a key to its // value; both backends must bind the names (the EIR VM used to drop the // pattern silently and bind nothing). Present keys read through.