From cfe37d36f7977f93dd5b8441d691811bf2b6997b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 14 Aug 2022 14:34:53 +0300 Subject: fix(tvix/eval): `or` should handle non-attrset values, too If a nested attrpath encounters a non-set value, the sentinel value denoting a lack of next values should be emitted. This mirrors the behaviour of Nix. Change-Id: Ia80443d5a11243cc6d98dcab1249a3f5fdf77e27 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6210 Reviewed-by: grfn Tested-by: BuildkiteCI --- .../src/tests/tvix_tests/eval-okay-or-operator-non-set.exp | 1 + .../src/tests/tvix_tests/eval-okay-or-operator-non-set.nix | 2 ++ tvix/eval/src/vm.rs | 14 +++++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.exp create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.nix (limited to 'tvix/eval/src') diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.exp new file mode 100644 index 0000000000..a833e32892 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.exp @@ -0,0 +1 @@ +"works fine" diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.nix new file mode 100644 index 0000000000..fd09bfee64 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-or-operator-non-set.nix @@ -0,0 +1,2 @@ +# `or` operator should keep working if it encounters a non-set type. +{ a.b = 42; }.a.b.c or "works fine" diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index d050fa8071..d18cd7977b 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -182,12 +182,16 @@ impl VM { OpCode::OpAttrOrNotFound => { let key = self.pop().to_string()?; - let attrs = self.pop().to_attrs()?; + let value = match self.pop() { + Value::Attrs(attrs) => match attrs.select(key.as_str()) { + Some(value) => value.clone(), + None => Value::NotFound, + }, - match attrs.select(key.as_str()) { - Some(value) => self.push(value.clone()), - None => self.push(Value::NotFound), - } + _ => Value::NotFound, + }; + + self.push(value); } OpCode::OpAttrsIsSet => { -- cgit 1.4.1