fix(tvix/eval): ?: propagate catchables

This commit fixes out `?` operator so it correctly propagates
catchables.

Change-Id: Iebaa153a8492101ee3ddd29893c98730ff331547
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10317
Autosubmit: Adam Joseph <adam@westernsemico.com>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Adam Joseph 2023-12-12 03:45:27 -08:00 committed by clbot
parent 990c4e727f
commit fc963033ae
3 changed files with 18 additions and 8 deletions

View file

@ -0,0 +1 @@
false

View file

@ -0,0 +1 @@
(builtins.tryEval ((throw "fred") ? bob)).success

View file

@ -707,16 +707,24 @@ impl<'o> VM<'o> {
} }
OpCode::OpHasAttr => { OpCode::OpHasAttr => {
let key = self.stack_pop().to_str().with_span(&frame, self)?; let key = self.stack_pop();
let result = match self.stack_pop() { let attrs = self.stack_pop();
Value::Attrs(attrs) => attrs.contains(key.as_str()), if key.is_catchable() {
self.stack.push(key);
} else if attrs.is_catchable() {
self.stack.push(attrs);
} else {
let key = key.to_str().with_span(&frame, self)?;
let result = match attrs {
Value::Attrs(attrs) => attrs.contains(key.as_str()),
// Nix allows use of `?` on non-set types, but // Nix allows use of `?` on non-set types, but
// always returns false in those cases. // always returns false in those cases.
_ => false, _ => false,
}; };
self.stack.push(Value::Bool(result)); self.stack.push(Value::Bool(result));
}
} }
OpCode::OpConcat => { OpCode::OpConcat => {