From 25921134353e785b509d4debeb11b3bf209c92b3 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Mon, 10 Oct 2022 15:57:54 -0400 Subject: [PATCH] fix(tvix/eval): Thunk `if` expr Since the body of an `if` expr can refer to deferred upvalues, it needs to be thunked so when we actually compile those deferred upvalues we have something for the finalize op to point at. Without this all sorts of weird things can happen due to the finalize op being run in the wrong lambda context, up to and including a panic. Change-Id: I040d5e1a7232fd841cfa4953539898fa49cbbb83 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6929 Reviewed-by: sterni Reviewed-by: tazjin Autosubmit: grfn Tested-by: BuildkiteCI --- tvix/eval/src/compiler/mod.rs | 4 +++- tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.exp | 1 + tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.nix | 6 ++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.exp create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.nix diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index cfb0ee64a..fa08d626a 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -212,7 +212,9 @@ impl Compiler<'_> { ast::Expr::Assert(assert) => { self.thunk(slot, assert, move |c, s| c.compile_assert(s, assert)) } - ast::Expr::IfElse(if_else) => self.compile_if_else(slot, if_else), + ast::Expr::IfElse(if_else) => { + self.thunk(slot, if_else, move |c, s| c.compile_if_else(s, if_else)) + } ast::Expr::LetIn(let_in) => self.compile_let_in(slot, let_in), ast::Expr::Ident(ident) => self.compile_ident(slot, ident), ast::Expr::With(with) => self.thunk(slot, with, |c, s| c.compile_with(s, with)), diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.exp new file mode 100644 index 000000000..ffcd4415b --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.exp @@ -0,0 +1 @@ +{ } diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.nix new file mode 100644 index 000000000..65e9e66d7 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-if.nix @@ -0,0 +1,6 @@ +let + a = {}; +in let + c = if builtins.isFunction a then a b else a; + b = {}; +in c