fix(tvix/eval): handle __toString when JSON-serialising attrsets

These must be serialised to a JSON string of the *result* of coercing
the function application to a string.

Change-Id: Ib7f49ccd950503ddbdbf99643cd59565e26b50da
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8204
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2023-03-03 23:55:00 +03:00 committed by tazjin
parent a9f44721e5
commit 7d339d2762
5 changed files with 29 additions and 0 deletions

View file

@ -359,6 +359,15 @@ mod pure_builtins {
#[builtin("toJSON")]
async fn builtin_to_json(co: GenCo, val: Value) -> Result<Value, ErrorKind> {
if let Value::Attrs(attrs) = &val {
// Attribute sets with a callable `__toString` attribute
// serialise to the string-coerced version of the result of
// calling that.
if let Some(s) = attrs.try_to_string(&co, CoercionKind::Weak).await {
return Ok(Value::String(serde_json::to_string(&s)?.into()));
}
}
// All thunks need to be evaluated before serialising, as the
// data structure is fully traversed by the Serializer.
let val = generators::request_deep_force(&co, val, SharedThunkSet::default()).await;