diff options
author | Adam Joseph <adam@westernsemico.com> | 2023-12-12T11·45-0800 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2023-12-12T16·57+0000 |
commit | fc963033ae0f28a387d6aebcc1e827439f6653ef (patch) | |
tree | a558df784931aa8745a59e66a59e260e62b6724e | |
parent | 990c4e727f000e7db94e9b1367a55dbbfca68d65 (diff) |
fix(tvix/eval): `?`: propagate catchables r/7189
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
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.nix | 1 | ||||
-rw-r--r-- | tvix/eval/src/vm/mod.rs | 24 |
3 files changed, 18 insertions, 8 deletions
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.exp new file mode 100644 index 000000000000..c508d5366f70 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.exp @@ -0,0 +1 @@ +false diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.nix new file mode 100644 index 000000000000..ba85d6b77644 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-hasattr-catchable.nix @@ -0,0 +1 @@ +(builtins.tryEval ((throw "fred") ? bob)).success diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs index 44a29ba86f9d..5b9aecb8d440 100644 --- a/tvix/eval/src/vm/mod.rs +++ b/tvix/eval/src/vm/mod.rs @@ -707,16 +707,24 @@ impl<'o> VM<'o> { } OpCode::OpHasAttr => { - let key = self.stack_pop().to_str().with_span(&frame, self)?; - let result = match self.stack_pop() { - Value::Attrs(attrs) => attrs.contains(key.as_str()), + let key = self.stack_pop(); + let attrs = self.stack_pop(); + 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 - // always returns false in those cases. - _ => false, - }; + // Nix allows use of `?` on non-set types, but + // always returns false in those cases. + _ => false, + }; - self.stack.push(Value::Bool(result)); + self.stack.push(Value::Bool(result)); + } } OpCode::OpConcat => { |