From eef48b8f1f3c7ae37a793bfef22c276dfd69767c Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Fri, 3 Mar 2023 10:54:35 +0300 Subject: fix(tvix/eval): correctly thunk deferred formals access Formals can be initialised with deferred default values (see the test cases), in which case they need an extra thunk to have something that can be finalised appropriately when the setup is done. Fixes: b/255 Change-Id: I380e3770be68eaa83ace96d450c7cead32dacc9f Reviewed-on: https://cl.tvl.fyi/c/depot/+/8196 Tested-by: BuildkiteCI Reviewed-by: raitobezarius --- tvix/eval/src/compiler/mod.rs | 12 +++++++++++- .../tests/tvix_tests/eval-okay-deferred-unary-formals.exp | 1 + .../tests/tvix_tests/eval-okay-deferred-unary-formals.nix | 6 ++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.exp create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-deferred-unary-formals.nix (limited to 'tvix/eval/src') 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; }) +] -- cgit 1.4.1