diff options
-rw-r--r-- | tvix/eval/src/value/attrs.rs | 12 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 2 |
2 files changed, 13 insertions, 1 deletions
diff --git a/tvix/eval/src/value/attrs.rs b/tvix/eval/src/value/attrs.rs index 4109691992ca..bbff79fc0d1a 100644 --- a/tvix/eval/src/value/attrs.rs +++ b/tvix/eval/src/value/attrs.rs @@ -66,6 +66,14 @@ impl AttrsRep { AttrsRep::Map(map) => map.get(&key.into()), } } + + fn contains(&self, key: &str) -> bool { + match self { + AttrsRep::Empty => false, + AttrsRep::KV { .. } => key == "name" || key == "value", + AttrsRep::Map(map) => map.contains_key(&key.into()), + } + } } #[repr(transparent)] @@ -202,6 +210,10 @@ impl NixAttrs { self.0.select(key) } + pub fn contains(&self, key: &str) -> bool { + self.0.contains(key) + } + /// Implement construction logic of an attribute set, to encapsulate /// logic about attribute set optimisations inside of this module. pub fn construct(count: usize, mut stack_slice: Vec<Value>) -> EvalResult<Self> { diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index b6d5a9838c3a..1e39792cd56f 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -242,7 +242,7 @@ impl VM { OpCode::OpAttrsIsSet => { let key = self.pop().to_string()?; let result = match self.pop() { - Value::Attrs(attrs) => attrs.select(key.as_str()).is_some(), + Value::Attrs(attrs) => attrs.contains(key.as_str()), // Nix allows use of `?` on non-set types, but // always returns false in those cases. |