about summary refs log tree commit diff
path: root/tvix/eval/src
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2023-12-13T12·17-0800
committertazjin <tazjin@tvl.su>2023-12-29T21·34+0000
commit2883b2d4bd948e090d46cee361bd69d6282d618c (patch)
tree9d5a082a2fed16b50f36740c13779b5f63c46b38 /tvix/eval/src
parent7ddea7340f547166a3c3f7fdd0afa776d9ba35aa (diff)
fix(tvix/eval): propagate catchables in string interpolations r/7275
Change-Id: I13d7ce0c7328a8e6fbc6d2c4ff5c4fe6095b96ea
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10357
Autosubmit: Adam Joseph <adam@westernsemico.com>
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src')
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.nix1
-rw-r--r--tvix/eval/src/vm/mod.rs12
3 files changed, 12 insertions, 2 deletions
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.exp
new file mode 100644
index 000000000000..c508d5366f70
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.exp
@@ -0,0 +1 @@
+false
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.nix
new file mode 100644
index 000000000000..7a0cf1670994
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-catchable-in-string-interpolation.nix
@@ -0,0 +1 @@
+(builtins.tryEval ("${toString 3}  ${throw "bob"}")).success
diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs
index 6c11997db1f5..92fa0f00e3d3 100644
--- a/tvix/eval/src/vm/mod.rs
+++ b/tvix/eval/src/vm/mod.rs
@@ -983,8 +983,16 @@ impl<'o> VM<'o> {
     fn run_interpolate(&mut self, frame: &CallFrame, count: usize) -> EvalResult<()> {
         let mut out = String::new();
 
-        for _ in 0..count {
-            out.push_str(self.stack_pop().to_str().with_span(frame, self)?.as_str());
+        for i in 0..count {
+            let val = self.stack_pop();
+            if val.is_catchable() {
+                for _ in (i + 1)..count {
+                    self.stack.pop();
+                }
+                self.stack.push(val);
+                return Ok(());
+            }
+            out.push_str(val.to_str().with_span(frame, self)?.as_str());
         }
 
         self.stack.push(Value::String(out.into()));