about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
authorRyan Lahfa <tvl@lahfa.xyz>2024-03-25T00·01+0100
committerraitobezarius <tvl@lahfa.xyz>2024-03-31T12·40+0000
commit8bccc9dca99bbd4d0f02d591fd11e425bf3aecc4 (patch)
tree74138e3d1ccf06c8db9e6667eb3ca4e781a880f3 /tvix/eval
parent94185f75604aca63c3d0e09a42503610f1dd822d (diff)
feat(tvix/eval): implement `unsafeDiscardOutputDependency` r/7806
This builtin only transforms any `NixContextElement::Derivation` into the trivial `NixContextElement::Plain`.

This is a forgetful functor on derivation-deep context strings.

The test coverage of this change is done in cl/11264.

Change-Id: Icd00778c97766be6db8a6bdabaa59e9724353ec5
Signed-off-by: Ryan Lahfa <tvl@lahfa.xyz>
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11262
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/docs/builtins.md2
-rw-r--r--tvix/eval/src/builtins/mod.rs42
-rw-r--r--tvix/eval/src/value/string.rs6
3 files changed, 43 insertions, 7 deletions
diff --git a/tvix/eval/docs/builtins.md b/tvix/eval/docs/builtins.md
index 26bbd1b2d3..4e09e0f9e6 100644
--- a/tvix/eval/docs/builtins.md
+++ b/tvix/eval/docs/builtins.md
@@ -120,7 +120,7 @@ The `impl` column indicates implementation status in tvix:
 | true                          | true   |       |       |         |
 | tryEval                       | false  |       |       |         |
 | typeOf                        | false  |       |       |         |
-| unsafeDiscardOutputDependency | false  |       |       | context |
+| unsafeDiscardOutputDependency | false  |       |       |         |
 | unsafeDiscardStringContext    | false  |       |       |         |
 | unsafeGetAttrPos              | false  |       |       | todo    |
 | valueSize                     | false  |       |       | todo    |
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs
index e1e296ba63..048c8867a7 100644
--- a/tvix/eval/src/builtins/mod.rs
+++ b/tvix/eval/src/builtins/mod.rs
@@ -1575,12 +1575,42 @@ mod placeholder_builtins {
         co: GenCo,
         s: Value,
     ) -> Result<Value, ErrorKind> {
-        generators::emit_warning_kind(
-            &co,
-            WarningKind::NotImplemented("builtins.unsafeDiscardOutputDependency"),
-        )
-        .await;
-        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()?;
+
+        // If there's any context, we will swap any ... by a path one.
+        if let Some(ctx) = v.context_mut() {
+            let new_context: tvix_eval::NixContext = ctx
+                .iter()
+                .map(|elem| match elem {
+                    // FUTUREWORK(performance): ideally, we should either:
+                    // (a) do interior mutation of the existing context.
+                    // (b) let the structural sharing make those clones cheap.
+                    crate::NixContextElement::Derivation(drv_path) => {
+                        crate::NixContextElement::Plain(drv_path.to_string())
+                    }
+                    elem => elem.clone(),
+                })
+                .collect::<HashSet<_>>()
+                .into();
+
+            *ctx = new_context;
+        }
+
+        Ok(Value::from(v))
     }
 
     #[builtin("addErrorContext")]
diff --git a/tvix/eval/src/value/string.rs b/tvix/eval/src/value/string.rs
index 6ce0d190c0..dd027895fd 100644
--- a/tvix/eval/src/value/string.rs
+++ b/tvix/eval/src/value/string.rs
@@ -48,6 +48,12 @@ impl From<NixContextElement> for NixContext {
     }
 }
 
+impl From<HashSet<NixContextElement>> for NixContext {
+    fn from(value: HashSet<NixContextElement>) -> Self {
+        Self(value)
+    }
+}
+
 impl NixContext {
     /// Creates an empty context that can be populated
     /// and passed to form a contextful [NixString], albeit