about summary refs log tree commit diff
path: root/tvix/eval/src/value/mod.rs
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2022-09-18T19·34-0400
committerclbot <clbot@tvl.fyi>2022-09-18T22·08+0000
commit6f70f325138b48f2c9b03a2103371663cb210d7c (patch)
treea5eeb3b027a98e387c2cc24a8999bc60f376c241 /tvix/eval/src/value/mod.rs
parent0b76ed5615eb48130773abf1e1a949e29b6cbd25 (diff)
fix(tvix/eval): Force thunks during equality comparison r/4910
Thunks might be encountered deep in equality comparison (eg nested
inside a list or attr-set), at which point we need to force them in
order to compare them for equality (or else we panic when trying to get
at their value).

Fixes: b/192
Change-Id: I912151085f8298f30d5214c7965251c9266443f2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6652
Autosubmit: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Diffstat (limited to 'tvix/eval/src/value/mod.rs')
-rw-r--r--tvix/eval/src/value/mod.rs13
1 files changed, 8 insertions, 5 deletions
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()),