diff options
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 12 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.nix | 6 |
3 files changed, 18 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index 5460514ba1ed..39b706cb487a 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -937,7 +937,17 @@ impl Compiler<'_> { let jump_over_default = self.push_op(OpCode::OpJump(JumpOffset(0)), &default_expr); self.patch_jump(jump_to_default); - self.compile(idx, default_expr); + + // Thunk the default expression, but only if it is something + // other than an identifier. + if let ast::Expr::Ident(_) = &default_expr { + self.compile(idx, default_expr); + } else { + self.thunk(idx, &self.span_for(&default_expr), move |c, s| { + c.compile(s, default_expr) + }); + } + self.patch_jump(jump_over_default); } else { self.push_op(OpCode::OpAttrsSelect, &entry.ident().unwrap()); diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.exp new file mode 100644 index 000000000000..5993db7ccc5a --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.exp @@ -0,0 +1 @@ +[ false -2 ] diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.nix new file mode 100644 index 000000000000..1fbb3e853af4 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.nix @@ -0,0 +1,6 @@ +# Application of unary operators on deferred formals arguments (via +# defaulting), see also b/255. +[ + (({ b ? !a, a }: b) { a = true; }) + (({ b ? -a, a }: b) { a = 2; }) +] |