about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
authorRyan Lahfa <tvl@lahfa.xyz>2023-12-25T23·38+0100
committerclbot <clbot@tvl.fyi>2024-01-03T16·45+0000
commit743c3620491dba67ebeaf439a4f0073f97d5e0af (patch)
tree5db1c6bf1099b4a8815d4c6a19ff2397116e7edf /tvix/eval
parent802f374a90d8202785a34648c39aa6320ac171d9 (diff)
feat(tvix/eval): context-aware `coerce_to_string` r/7317
I am still undecided whether we need a CoercionKind to control
the coerced context, here's a simple attempt.

Change-Id: Ibe59d09ef26c519a6acfdfe392014446646dd6d8
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10426
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Autosubmit: raitobezarius <tvl@lahfa.xyz>
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/value/mod.rs16
-rw-r--r--tvix/eval/src/value/string.rs4
2 files changed, 18 insertions, 2 deletions
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index 16eb2a66b3fb..b688716d4131 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -318,15 +318,27 @@ impl Value {
         // Track if we are coercing the first value of a list to correctly emit
         // separating white spaces.
         let mut is_list_head = None;
+        // FIXME(raitobezarius): as per https://b.tvl.fyi/issues/364
+        // we might be interested into more powerful context-related coercion kinds.
+        let mut context: NixContext = NixContext::new();
+
         loop {
             let value = if let Some(v) = vals.pop() {
                 v.force(co, span.clone()).await?
             } else {
-                return Ok(Value::String(result.into()));
+                return Ok(Value::String(NixString::new_context_from(
+                    context,
+                    result.as_str(),
+                )));
             };
             let coerced = match (value, kind) {
                 // coercions that are always done
-                (Value::String(s), _) => Ok(s.as_str().to_owned()),
+                (Value::String(mut s), _) => {
+                    if let Some(ctx) = s.context_mut() {
+                        context = context.join(ctx);
+                    }
+                    Ok(s.as_str().to_owned())
+                }
 
                 // TODO(sterni): Think about proper encoding handling here. This needs
                 // general consideration anyways, since one current discrepancy between
diff --git a/tvix/eval/src/value/string.rs b/tvix/eval/src/value/string.rs
index 56f9a3f8606a..aa82ed36eb40 100644
--- a/tvix/eval/src/value/string.rs
+++ b/tvix/eval/src/value/string.rs
@@ -322,6 +322,10 @@ impl NixString {
         Self::new_context_from(context, &s.into_boxed_str())
     }
 
+    pub(crate) fn context_mut(&mut self) -> Option<&mut NixContext> {
+        return self.1.as_mut();
+    }
+
     pub fn iter_plain(&self) -> impl Iterator<Item = &str> {
         return self.1.iter().flat_map(|context| context.iter_plain());
     }