diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-14T11·27+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-30T17·13+0000 |
commit | 76846fe22032546661cdf8649b8f898fc36e5270 (patch) | |
tree | 2f1d71baedc21a21b350706e29a8cef0f06b4605 | |
parent | 43658a5b90786eb169471f02e6738359214343d9 (diff) |
fix(tvix/eval): allow use of ? operator on non-set types r/4542
Nix allows this, but always returns false. Tvix needs to do the same. Change-Id: Ic9eec90834a0d0969eea5316d5c25032d3691d94 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6209 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.nix | 3 | ||||
-rw-r--r-- | tvix/eval/src/value/mod.rs | 2 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 12 |
4 files changed, 14 insertions, 4 deletions
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.exp new file mode 100644 index 000000000000..ca00e3c049d6 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.exp @@ -0,0 +1 @@ +[ false false false false ] diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.nix new file mode 100644 index 000000000000..c086759f456b --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-contains-non-set.nix @@ -0,0 +1,3 @@ +# Nix allows using the ? operator on non-set types, in which case it +# should always return false. +[ (123 ? key) ("foo" ? key) (null ? key) ([ "key" ] ? key) ] diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index 46021a167b27..f0cc86eedac4 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -116,7 +116,7 @@ impl Display for Value { } // internal types - Value::AttrPath(_) => f.write_str("internal[attrpath]"), + Value::AttrPath(path) => write!(f, "internal[attrpath({})]", path.len()), Value::Blackhole => f.write_str("internal[blackhole]"), Value::NotFound => f.write_str("internal[not found]"), } diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index f96a5dcbddaf..d050fa807106 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -192,9 +192,15 @@ impl VM { OpCode::OpAttrsIsSet => { let key = self.pop().to_string()?; - let attrs = self.pop().to_attrs()?; - let result = Value::Bool(attrs.select(key.as_str()).is_some()); - self.push(result); + let result = match self.pop() { + Value::Attrs(attrs) => attrs.select(key.as_str()).is_some(), + + // Nix allows use of `?` on non-set types, but + // always returns false in those cases. + _ => false, + }; + + self.push(Value::Bool(result)); } OpCode::OpList(count) => { |