From dad8a7cbffbb0fac850e081e564eb09c67dd2fca Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Mon, 21 Nov 2022 20:04:12 -0800 Subject: feat(tvix/eval): non-recursive implementation of nix_eq() This passes all the function/thunk-pointer-equality tests in cl/7369. Change-Id: Ib47535ba2fc77a4f1c2cc2fd23d3a879e21d8b4c Signed-off-by: Adam Joseph Reviewed-on: https://cl.tvl.fyi/c/depot/+/7358 Tested-by: BuildkiteCI Reviewed-by: tazjin --- tvix/eval/src/value/mod.rs | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) (limited to 'tvix/eval/src/value/mod.rs') diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index d777816bb31f..1763b716ee45 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -313,7 +313,6 @@ impl Value { // Trivial comparisons (Value::Null, Value::Null) => Ok(true), (Value::Bool(b1), Value::Bool(b2)) => Ok(b1 == b2), - (Value::List(l1), Value::List(l2)) => l1.nix_eq(l2, vm), (Value::String(s1), Value::String(s2)) => Ok(s1 == s2), (Value::Path(p1), Value::Path(p2)) => Ok(p1 == p2), @@ -323,31 +322,10 @@ impl Value { (Value::Float(f1), Value::Float(f2)) => Ok(f1 == f2), (Value::Float(f), Value::Integer(i)) => Ok(*i as f64 == *f), - // 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 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)?; - - // TODO: this cloning is done because there is a potential issue - // with keeping borrows into both thunks around while recursing, - // as they might recurse themselves, leading to a borrow error - // when they are later being forced. - let lhs = lhs.value().clone(); - let rhs = rhs.value().clone(); - lhs.nix_eq(&rhs, vm) - } - (Value::Thunk(lhs), rhs) => { - lhs.force(vm)?; - lhs.value().nix_eq(rhs, vm) - } - (lhs, Value::Thunk(rhs)) => { - rhs.force(vm)?; - lhs.nix_eq(&*rhs.value(), vm) - } + (Value::Attrs(_), Value::Attrs(_)) + | (Value::List(_), Value::List(_)) + | (Value::Thunk(_), _) + | (_, Value::Thunk(_)) => Ok(vm.nix_eq(self.clone(), other.clone(), false)?), // Everything else is either incomparable (e.g. internal // types) or false. -- cgit 1.4.1