about summary refs log tree commit diff
path: root/tvix/eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src')
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.nix11
-rw-r--r--tvix/eval/src/value/mod.rs13
3 files changed, 20 insertions, 5 deletions
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.exp
new file mode 100644
index 000000000000..e6f2d1aaadd2
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.exp
@@ -0,0 +1 @@
+[ true true false ]
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.nix
new file mode 100644
index 000000000000..b0ec8593a468
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-equality.nix
@@ -0,0 +1,11 @@
+let
+  attrs1 = { x = 1 + 2; };
+  attrs2 = { x = 2 + 1; };
+  list1 = [ (1 + 2) ];
+  list2 = [ (2 + 1) ];
+  list3 = [ (2 + 2) ];
+in [
+  (attrs1 == attrs2)
+  (list1 == list2)
+  (list3 == list2)
+]
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index 8a2ab19961cf..b628d7c4ee8f 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -275,11 +275,14 @@ impl Value {
             // Optimised attribute set comparison
             (Value::Attrs(a1), Value::Attrs(a2)) => Ok(Rc::ptr_eq(a1, a2) || a1.nix_eq(a2, vm)?),
 
-            // If either value is a thunk, the inner value must be
-            // compared instead. The compiler should ensure that
-            // thunks under comparison have been forced, otherwise it
-            // is a bug.
-            (Value::Thunk(lhs), Value::Thunk(rhs)) => Ok(*lhs.value() == *rhs.value()),
+            // If either value is a thunk, the thunk should be forced, and then the resulting value
+            // must be compared instead.
+            (Value::Thunk(lhs), Value::Thunk(rhs)) => {
+                lhs.force(vm)?;
+                rhs.force(vm)?;
+
+                Ok(*lhs.value() == *rhs.value())
+            }
             (Value::Thunk(lhs), rhs) => Ok(&*lhs.value() == rhs),
             (lhs, Value::Thunk(rhs)) => Ok(lhs == &*rhs.value()),