feat(tvix/eval): impl unsafeDiscardStringContext

Change-Id: I7f0cc42cbebfe5cd27bf6d4f58a4af927b83646a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10423
Autosubmit: raitobezarius <tvl@lahfa.xyz>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Ryan Lahfa 2023-12-25 22:07:14 +01:00 committed by clbot
parent 099ca6b7c0
commit 556e52c9cb
3 changed files with 65 additions and 5 deletions

View file

@ -121,7 +121,7 @@ The `impl` column indicates implementation status in tvix:
| tryEval | false | | | |
| typeOf | false | | | |
| unsafeDiscardOutputDependency | false | | | context |
| unsafeDiscardStringContext | false | | | context |
| unsafeDiscardStringContext | false | | | |
| unsafeGetAttrPos | false | | | todo |
| valueSize | false | | | todo |

View file

@ -1348,11 +1348,26 @@ mod placeholder_builtins {
#[builtin("unsafeDiscardStringContext")]
async fn builtin_unsafe_discard_string_context(
_: GenCo,
#[lazy] s: Value,
co: GenCo,
s: Value,
) -> Result<Value, ErrorKind> {
// Tvix does not manually track contexts, and this is a no-op for us.
Ok(s)
let span = generators::request_span(&co).await;
let mut v = s
.coerce_to_string(
co,
// It's weak because
// lists, integers, floats and null are not
// accepted as parameters.
CoercionKind {
strong: false,
import_paths: true,
},
span,
)
.await?
.to_contextful_str()?;
v.clear_context();
Ok(Value::String(v))
}
#[builtin("addErrorContext")]

View file

@ -143,6 +143,51 @@ mod tests {
);
}
/// Construct two derivations with the same parameters except
/// one of them lost a context string for a dependency, causing
/// the loss of an element in the `inputDrvs` derivation.
/// Therefore, making `outPath` different.
#[test]
fn test_unsafe_discard_string_context() {
let code = r#"
let
dep = builtins.derivation { name = "foo"; builder = "/bin/sh"; system = "x86_64-linux"; };
in
(builtins.derivation { name = "foo"; builder = "/bin/sh"; system = "x86_64-linux"; env = "${dep}"; }).outPath !=
(builtins.derivation { name = "foo"; builder = "/bin/sh"; system = "x86_64-linux"; env = "${builtins.unsafeDiscardStringContext dep}"; }).outPath
"#;
let value = eval(code).value.expect("must succeed");
match value {
tvix_eval::Value::Bool(v) => {
assert!(v);
}
_ => panic!("unexpected value type: {:?}", value),
}
}
/// Construct an attribute set
/// that coerces to a derivation
/// and verify that the return type is a string.
#[test]
fn test_unsafe_discard_string_context_of_coercible() {
let code = r#"
let
dep = builtins.derivation { name = "foo"; builder = "/bin/sh"; system = "x86_64-linux"; };
attr = { __toString = _: dep; };
in
builtins.typeOf (builtins.unsafeDiscardStringContext attr) == "string"
"#;
let value = eval(code).value.expect("must succeed");
match value {
tvix_eval::Value::Bool(v) => {
assert!(v);
}
_ => panic!("unexpected value type: {:?}", value),
}
}
#[test]
fn builtins_placeholder_hashes() {
assert_eq!(