From 289663cac4c1acd75ea850f1622ec8fee9eeff44 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Mon, 11 Dec 2023 22:48:31 -0800 Subject: [PATCH] fix(tvix/eval): handle catchables in attribute set updates Fixes b/346. Change-Id: I277121d2363e605ebe09651ed9440fe1bc126c8c Reviewed-on: https://cl.tvl.fyi/c/depot/+/10292 Tested-by: BuildkiteCI Autosubmit: Adam Joseph Reviewed-by: tazjin --- .../eval-okay-catchable-in-update-attrs.exp | 0 .../eval-okay-catchable-in-update-attrs.nix | 0 tvix/eval/src/vm/mod.rs | 15 +++++++++++---- 3 files changed, 11 insertions(+), 4 deletions(-) rename tvix/eval/src/tests/tvix_tests/{notyetpassing => }/eval-okay-catchable-in-update-attrs.exp (100%) rename tvix/eval/src/tests/tvix_tests/{notyetpassing => }/eval-okay-catchable-in-update-attrs.nix (100%) diff --git a/tvix/eval/src/tests/tvix_tests/notyetpassing/eval-okay-catchable-in-update-attrs.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-update-attrs.exp similarity index 100% rename from tvix/eval/src/tests/tvix_tests/notyetpassing/eval-okay-catchable-in-update-attrs.exp rename to tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-update-attrs.exp diff --git a/tvix/eval/src/tests/tvix_tests/notyetpassing/eval-okay-catchable-in-update-attrs.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-update-attrs.nix similarity index 100% rename from tvix/eval/src/tests/tvix_tests/notyetpassing/eval-okay-catchable-in-update-attrs.nix rename to tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-update-attrs.nix diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs index 642b6317c..312d1b893 100644 --- a/tvix/eval/src/vm/mod.rs +++ b/tvix/eval/src/vm/mod.rs @@ -661,10 +661,17 @@ impl<'o> VM<'o> { OpCode::OpAttrs(Count(count)) => self.run_attrset(&frame, count)?, OpCode::OpAttrsUpdate => { - let rhs = self.stack_pop().to_attrs().with_span(&frame, self)?; - let lhs = self.stack_pop().to_attrs().with_span(&frame, self)?; - - self.stack.push(Value::attrs(lhs.update(*rhs))) + let rhs = self.stack_pop(); + let lhs = self.stack_pop(); + if lhs.is_catchable() { + self.stack.push(lhs); + } else if rhs.is_catchable() { + self.stack.push(rhs); + } else { + let rhs = rhs.to_attrs().with_span(&frame, self)?; + let lhs = lhs.to_attrs().with_span(&frame, self)?; + self.stack.push(Value::attrs(lhs.update(*rhs))) + } } OpCode::OpInvert => {