diff options
author | Vincent Ambo <mail@tazj.in> | 2023-01-23T13·35+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2023-01-23T17·27+0000 |
commit | d2f1a290a43f7a337ddfed78e382bf6c13d798c1 (patch) | |
tree | 5201a8afbad17f03248abc226529bc4eaa58a557 /tvix/eval | |
parent | b5d1ae4722d3f28f7ee005ddb402a212530f938f (diff) |
fix(tvix/eval): force functors before applying them r/5746
call_value in the VM expects the callable to be forced when calling it, which was not the case for functors. Change-Id: Id55a2fe32a9573be42aef8669e268df519a989cd Reviewed-on: https://cl.tvl.fyi/c/depot/+/7909 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.nix | 7 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 4 |
3 files changed, 12 insertions, 0 deletions
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.exp new file mode 100644 index 000000000000..d81cc0710eb6 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.exp @@ -0,0 +1 @@ +42 diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.nix new file mode 100644 index 000000000000..f8eba2ac2fc0 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-thunked-functor.nix @@ -0,0 +1,7 @@ +let + __functor = f; + f = self: x: self.out * x; +in { + inherit __functor; + out = 21; +} 2 diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 818b5ff9b1f7..93bf853f9c26 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -406,6 +406,10 @@ impl<'o> VM<'o> { Value::Attrs(ref attrs) => match attrs.select("__functor") { None => Err(self.error(ErrorKind::NotCallable(callable.type_of()))), Some(functor) => { + if let Value::Thunk(thunk) = &functor { + fallible!(self, thunk.force(self)); + } + // The functor receives the set itself as its first argument // and needs to be called with it. However, this call is // synthetic (i.e. there is no corresponding OpCall for the |