about summary refs log tree commit diff
AgeCommit message (Collapse)AuthorFilesLines
2022-08-26 r/4506 fix(tvix/compiler): handle literal URL valuesVincent Ambo1-1/+8
The parser creates this node type from literal URL values. Technically these are deprecated and have been removed from nixpkgs. Change-Id: I4d05034dd9b4d8348e4ed8a2bbb37c1b6ccef8bc Reviewed-on: https://cl.tvl.fyi/c/depot/+/6173 Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-08-26 r/4505 feat(tvix/eval): use rustyline crate for REPLVincent Ambo1-19/+49
This is a substantially nicer experience, immediately granting us history, proper exiting and so on. Change-Id: Iba4cb1713b9ac53d0799722bdbe2cd0e94a2f527 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6171 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-26 r/4504 chore(tvix/cargo): add dirs dependencyVincent Ambo2-0/+22
This crate provides sensible default locations for directories on different platforms. Change-Id: I0b61cc7f626dc6c8df903ba0f873be24e07d69b5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6170 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-26 r/4503 chore(tvix/cargo): add rustyline dependencyVincent Ambo2-0/+291
There's a few options for this, but this one seems fine in terms of features and doesn't have an insane amount of dependencies. Change-Id: Ief99e66bfee0ba0ba1cfdd09568b002121b7325b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6169 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-26 r/4502 style(tvix/eval): minor rephrasing in a commentVincent Ambo1-1/+1
From cl/6070 Change-Id: I8ce8c1b40032d85cd2c01b04e225ae4a2842c7b7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6172 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-26 r/4501 test(tvix/eval): add tests for the attrset `or` operatorVincent Ambo8-0/+8
Change-Id: I81f3ab94d8b987f5a4c87a27b2bcbb49cccee1ce Reviewed-on: https://cl.tvl.fyi/c/depot/+/6168 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-26 r/4500 feat(tvix/compiler): implement `or` operator for attribute setsVincent Ambo1-2/+76
This operator allows for accessing attribute sets (including nested access) while also providing a default value. This is one of the more complex operations to compile, as it needs to keep track of a fairly large number of jumps that all need to be patched correctly. To make this easier to understand there's a small diagram included in the comments. Change-Id: Ia53bb20d8f779859bfd1692fa3f6d72af74c3a1f Reviewed-on: https://cl.tvl.fyi/c/depot/+/6167 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-26 r/4499 feat(tvix/vm): add opcodes for new Value::NotFound sentinelVincent Ambo3-3/+24
This sentinel value is going to be used for certain nested accesses into attribute sets. There is a new instruction similar to `OpAttrsSelect` which leaves the sentinel on the stack if a key is not found, instead of raising an error. Additionally, a new jump instruction makes its jump operation conditional on finding such a sentinel value. Change-Id: I2642f0a0bcc85bbe0ead68ea09a7dd794dbedeac Reviewed-on: https://cl.tvl.fyi/c/depot/+/6166 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-26 r/4498 refactor(tvix/value): replace static representation with SmolStrVincent Ambo5-12/+15
The only uses of the static variant were for `"name"` and `"value"`, which are both small enough to fit into a SmolStr. The size of NixString accomodates `String` anyways, so we may as well inline them. Additionally smol_str is already in the dependency graph because rnix uses it, and using it for representations of identifiers is sensible. Change-Id: I9969312256d1657d69128e54c47dc7294a18ce58 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6165 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 r/4497 chore(tvix/eval): implement improved Display for internal valuesVincent Ambo1-1/+2
Having these visible more explicitly is useful while debugging. Change-Id: I86b497883063d32792b635eb4514b7aeae484af4 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6164 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 r/4496 feat(tvix/eval): implement nested '?' operatorVincent Ambo1-13/+25
Implements the nested presence check operator for attribuet sets by traversing the chain of lookups through instructions that push/pop sequentially deeper attribute sets onto the stack. Note that this commit introduces a bug in case of nested attributes not being found, which is fixed in a later commit. Change-Id: Ic8b4c8648736f6cb048e3aa52592e4d075bf0544 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6163 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 r/4495 feat(tvix/eval): implement `?` operator (single-level only)Vincent Ambo3-7/+50
This makes it possible to check things like `{} ? a` with a single level of nesting. Change-Id: I567c36fcfd2f9e2f60071acd3ebfe56dea59b26f Reviewed-on: https://cl.tvl.fyi/c/depot/+/6161 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-26 r/4494 feat(tvix/compiler): handle dynamic nodes for attribute accessVincent Ambo1-3/+4
Dynamic nodes (essentially unquoted interpolation) simply need to be unwrapped (and, hopefully, evaluate to a string). Example: `let key = "a"; in { a = 1; }.${key}` Change-Id: Idafd376e19d0e237151b7b6c26d97713beae5041 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6160 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 r/4493 fix(tvix/compiler): support identifier literals in select expressionVincent Ambo1-1/+19
With this change, attribute set access is working as intended. Change-Id: Ic5dbbd68aa59156106069289e7375a696909f78b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6159 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 r/4492 feat(tvix/eval): implement attribute set access operatorVincent Ambo5-4/+65
Fairly straightforward, handling the optimised representations manually and otherwise delegating to BTreeMap. Note that parsing of raw identifiers is not yet implemented. Encountering an identifier node usually means that there is locals access going on, so we need a special case for compiling a node in such a way that an identifier's literal value ends up on the stack. Change-Id: I13fbab7ac657b17ef3f4c5859fe737c321890c8a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6158 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 r/4491 fix(tvix/eval): add operation to assert boolean typeVincent Ambo4-0/+24
This operation is required because both sides of the logical operators are strictly evaluated by Nix, even if the resulting value is not used further. For example, in our implementation of `&&`, if the left-hand side is `true`, then the result of the expression is simply the right-hand side value. This value must be asserted to be a boolean for the semantics of the language to work correctly. Change-Id: I34f5364f2a444753fa1d8b0a1a2b2d9cdf7c6700 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6157 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-25 r/4490 fix: reflect renames of Nix configuration optionssterni5-28/+24
Change-Id: I7e28ac3d71acd7d99a1d3ef97bef9422097e4abf Reviewed-on: https://cl.tvl.fyi/c/depot/+/6154 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
2022-08-25 r/4489 feat(tvix/eval): Add initial benchmarking infrastructureGriffin Smith3-6/+574
Bootstrap some (initially very simple, mostly proof-of-concept) benchmarking infrastructure using Criterion, using the newly-exposed lib from tvix-eval. Change-Id: I4bb93c142ba8d018d7e67e58ac8907a0429398a5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6156 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI Autosubmit: grfn <grfn@gws.fyi>
2022-08-25 r/4488 feat(tvix/eval): Expose interpret + related types from libGriffin Smith2-12/+15
Add a new `lib.rs` to tvix/eval, which `pub use`s the `interpret` function, and all types mentioned in its return type, and then uses *this* instead of direct `mod` statements in the `main.rs` to implement the entrypoints to the interpreter. This is in preparation for calling these functions from integrated benchmarking infrastructure using Criterion, though other things (like integration tests) might want to do that as well. Change-Id: I7b585134a96b1c56a2ac64d2036b0e51d321bd27 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6155 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI Autosubmit: grfn <grfn@gws.fyi>
2022-08-25 r/4487 feat(tvix/compiler): implement `->` (implication) operatorVincent Ambo1-1/+21
Similar to `||`, but inverting the left-hand side. In other words, `a -> b` is essentially rewritten as `!a || b`. Change-Id: I8a62da65ff070b389e46048d047a54279060a97b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6152 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4486 feat(tvix/compiler): implement `||` operatorVincent Ambo3-6/+29
Same dance as `&&` but logically inverted. Change-Id: I213e200e3836527e9abe510f354ee7cd1f70d041 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6151 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4485 feat(tvix/compiler): implement `&&` operatorVincent Ambo1-7/+41
This logical operator is implemented in terms of jumping operations and thus requires slightly different treatment than other binary operators. Change-Id: Ib3d768b70dd7e16014c9b47d770aa74eec60ae92 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6150 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4484 docs(tvix/compiler): add a note on use of unwrap/expect for rnixVincent Ambo1-0/+12
Change-Id: I62ca28285685b69d1883afcf18c6068fc2defb5d Reviewed-on: https://cl.tvl.fyi/c/depot/+/6149 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4483 feat(tvix/eval): implement if/else expressionsVincent Ambo4-5/+84
These expressions use simple jumps to skip the correct expression conditionally in the bytecode by advancing the instruction pointer. Note that these expressions are already covered by a test behind the `nix_tests` feature flag, but adding more is probably sensible. Change-Id: Ibe0eba95d216321c883d3b6b5816e2ab6fe7eef1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6148 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4482 refactor(tvix/value): hide internal string representationVincent Ambo2-13/+16
Wraps the string representation in an additional newtype struct with a private field in order to hide the representation from other modules. This is done in order to avoid accidental leakage of the internals outside of value::string. In fact, this caught a mistake in the compiler module which was directly constructing an internal variant. Change-Id: If4b627d3cff7ab9cd50ca1a3ac73245d4dcf7aef Reviewed-on: https://cl.tvl.fyi/c/depot/+/6147 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4481 refactor(tvix/value): ensure internal attrs representation is hiddenVincent Ambo2-47/+53
Wraps the attrs representation in an additional newtype struct with a private field in order to hide the representation from other modules. This is done in order to avoid accidental leakage of the internals outside of value::attrs. Change-Id: I68d1d02514aa0443df4c39801001a3f1f6cc5d5c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6146 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4480 refactor(tvix/eval): encapsulate list construction in value::listVincent Ambo2-17/+17
Ensuring that the implementation is not leaking out of the module lets us keep things open for optimisations (e.g. empty list or pairs through tuples). Change-Id: I18fd9b7740f28c55736471e16c6b4095a05dd6d0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6145 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4479 feat(tvix/eval): implement list concatenationVincent Ambo7-0/+30
Change-Id: Icdf715d116371a9f139bdf95266410bf967bef25 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6144 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-08-25 r/4478 feat(tvix/eval): implement binary comparison operatorsVincent Ambo20-7/+121
This is accomplished by simply delegating to the Rust implementations of (Partial)Ord and (Partial)Eq, which are implemented for Value and underlying wrapper types to behave like they do in Nix. To ease the implementation overhead, a new comparison operator macro has been added to the VM module. Incomparable types will raise a new error variant when a comparison is attempted, containing both supplied types. This mimics the information carried in the error thrown by C++ Nix. Change-Id: Ia19634d69119d40722f3ca672387bc3a80096998 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6143 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-08-25 r/4477 refactor(tvix/vm): simplify implementation of OpEqualVincent Ambo1-8/+1
This can now fully delegate to PartialEq of Value Change-Id: Iaa9f4ec9b8830d516d72f83a93ab2df9a6e5697c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6142 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4476 feat(tvix): implement not-equals (!=) operatorVincent Ambo9-8/+21
Change-Id: Ic259d6d0cf30553e944682a0d1d2c610df7fe5c2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6141 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-08-25 r/4475 feat(tvix/eval): implement attrset update (`//`) operatorVincent Ambo13-1/+87
The underlying implementation does a few tricks based on which pair of attrset representations is encountered. Particularly the effect of short-circuiting the empty cases might be relevant in nixpkgs/NixOS, due to the use of lib.optionalAttrs. Change-Id: I22b978b1c69af12926489a71087c6a6219c012f3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6140 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-08-25 r/4474 fix(tvix/value): explicitly delegate `Ord` to &str representationVincent Ambo1-1/+9
I assumed that `Ord` is a marker trait like `Eq`, but it actually has a member. Without this ordering was incoherent. Change-Id: Id37cbdf333daf748d29b85243046c7e061b1ce29 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6139 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4473 fix(tvix/value): ensure only string values of NixString are hashedVincent Ambo1-1/+8
Change-Id: I1b97cf5a9e4e235fac72a507de49a8df508bcaa1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6138 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4472 feat(tvix/eval): implement string concatenationVincent Ambo6-1/+23
Change-Id: If61066e59232b2bad42b5cb5f0f2d9b9c416be8b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6137 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4471 refactor(tvix/vm): use a macro to handle binary arithmetic operatorsVincent Ambo1-49/+32
Instead of constructing another runtime value representing the pair on which to perform arithmetic, implement the same logic in the shape of a macro. This is designed to be compatible with operators like `+` that work both as an arithmetic operator AND as an operator on another pair of types. Change-Id: I1c83649ead6117f811f1fb45482d0cadf811125e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6136 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4470 test(tvix/eval): add some eval-okay-* tests for trivial typesVincent Ambo13-16/+50
Change-Id: I85ccc07e08c67abf4fcd3752c58e1702943239ac Reviewed-on: https://cl.tvl.fyi/c/depot/+/6135 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 r/4469 fix(tvix/value): fix display representation of floatsVincent Ambo1-1/+7
Nix displays a maximum of 5 digits for floating points. Change-Id: Ifa3c0d96fa0b24e3be8f94dfebc99e602a258355 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6133 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-24 r/4468 chore(tvix/eval): enable test runs in naerskVincent Ambo1-0/+1
Change-Id: I08c3a66a3f5c98d914d17a2ad6de98b1c02e50b2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6134 Tested-by: BuildkiteCI Autosubmit: tazjin <tazjin@tvl.su> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4467 test(tvix/eval): add identity tests for literal evaluationVincent Ambo19-2/+56
Change-Id: Id3f37fbe341e15e9428ef1d579d61a514232c0e8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6132 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4466 fix(tvix/value): align Display representation with NixVincent Ambo1-6/+2
Displaying the optimised representation is not useful anymore. Change-Id: Icb962ff8865ec4207c144fbcb1aae87483b0fb7c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6131 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4465 docs(tvix/eval): add README note on running the Nix test suiteVincent Ambo1-0/+12
Change-Id: I792154d5fea05414f2b14367ea4087dc2a88758e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6130 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4464 chore(tvix/tests): gate Nix test suite behind `nix_tests` featureVincent Ambo2-0/+6
Once we have full coverage they should be enabled by default. Change-Id: Iace9e1ae9a9f901a0979ad336434004b8028fe8a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6129 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4463 chore(tvix/eval): only print AST if requestedVincent Ambo1-1/+3
Change-Id: If32c7fd03458a27aecb8c473f2c48b12f8cb5175 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6128 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su>
2022-08-24 r/4462 fix(tvix/value): add ident_str representation of stringsVincent Ambo2-8/+25
When printing strings as identifiers (in attribute sets), the string should only be quoted and escaped if it contains escape characters. Change-Id: If2bcfa1e93dc8f00be4d7a57ec1d82fc679103c3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6127 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su>
2022-08-24 r/4461 feat(tvix/tests): check in Nix' language test suiteVincent Ambo248-9/+2217
This adds scaffolding code for running the Nix language test suite. The majority of eval-okay-* tests should eventually be runnable as-is by Tvix, however the eval-fail-* tests might not as we intend to have more useful error messages than upstream Nix. Change-Id: I4f3227f0889c55e4274b804a3072850fb78dd1bd Reviewed-on: https://cl.tvl.fyi/c/depot/+/6126 Tested-by: BuildkiteCI Autosubmit: tazjin <tazjin@tvl.su> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4460 chore(tvix/eval): add 'test-generator' as dev-dependencyVincent Ambo2-0/+57
This crate makes it easy to generate test cases from files on disk, which is used for running the Nix test suite against Tvix. Change-Id: I60ef26484d05e723982679dd42958adf52735916 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6125 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4459 fix(tvix/value): add escaping logic for Nix stringsVincent Ambo1-10/+46
Nix strings displayed to users must be escaped the same way as they are in C++ Nix. This adds the scaffolding for escapes, but is most likely not yet complete. Change-Id: Icfdcb2ac98d292c567ba894a92b6529a53e0cc17 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6124 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 r/4458 fix(tvix/value): implement PartialOrd/PartialEq for stringsVincent Ambo1-1/+13
Instead of comparing the enum variants (which does not yield useful behaviour), compare &str representations of the string instead. Change-Id: I5e94b5f6c91b4561e1bc7c36d586f3d23c243764 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6112 Tested-by: BuildkiteCI Reviewed-by: eta <tvl@eta.st>
2022-08-24 r/4457 feat(tvix/value): introduce string representation with &'static strVincent Ambo4-26/+44
For cases where the strings are statically known (such as the oft-occuring name/value), this can be a useful optimisation. It's also much more convenient in tests. Change-Id: Ie462b684805bd4986ea5e85ca4bff663bc2d3c3c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6111 Tested-by: BuildkiteCI Reviewed-by: eta <tvl@eta.st>