about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
authorRyan Lahfa <tvl@lahfa.xyz>2023-12-25T23·40+0100
committerclbot <clbot@tvl.fyi>2024-01-03T23·24+0000
commitf44ac2a5940a93248ec9cff83856208bd629ae20 (patch)
tree6d34a4bb0fd5d6be826fded7e8542a79ad1d07a4 /tvix/eval
parent556e52c9cb8aa7b2af8bae75cd3365318e5d08c2 (diff)
feat(tvix/eval): context-aware `split` r/7340
Nix does something like:

```cpp
        NixStringContext context;
        const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
```

And then do nothing with that context, therefore, we follow them and
make `split` aware of the context but still do nothing with it.

Change-Id: I4fee1936600ce86d99d00893ca3f64013213935b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10428
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: raitobezarius <tvl@lahfa.xyz>
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/builtins/mod.rs19
1 files changed, 14 insertions, 5 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs
index b5adc3775fc0..a35c51099061 100644
--- a/tvix/eval/src/builtins/mod.rs
+++ b/tvix/eval/src/builtins/mod.rs
@@ -1060,7 +1060,7 @@ mod pure_builtins {
 
     #[builtin("split")]
     async fn builtin_split(co: GenCo, regex: Value, str: Value) -> Result<Value, ErrorKind> {
-        let s = str.to_str()?;
+        let s = str.to_contextful_str()?;
         let text = s.as_str();
         let re = regex.to_str()?;
         let re: Regex = Regex::new(re.as_str()).unwrap();
@@ -1071,7 +1071,10 @@ mod pure_builtins {
 
         while let Some(thematch) = re.captures_read_at(&mut capture_locations, text, pos) {
             // push the unmatched characters preceding the match
-            ret.push_back(Value::from(&text[pos..thematch.start()]));
+            ret.push_back(Value::from(NixString::new_inherit_context_from(
+                &s,
+                &text[pos..thematch.start()],
+            )));
 
             // Push a list with one element for each capture
             // group in the regex, containing the characters
@@ -1080,8 +1083,12 @@ mod pure_builtins {
             let v: imbl::Vector<Value> = (1..num_captures)
                 .map(|i| capture_locations.get(i))
                 .map(|o| {
-                    o.map(|(start, end)| Value::from(&text[start..end]))
-                        .unwrap_or(Value::Null)
+                    o.map(|(start, end)| {
+                        // Here, a surprising thing happens: we silently discard the original
+                        // context. This is as intended, Nix does the same.
+                        Value::from(&text[start..end])
+                    })
+                    .unwrap_or(Value::Null)
                 })
                 .collect();
             ret.push_back(Value::List(NixList::from(v)));
@@ -1089,6 +1096,8 @@ mod pure_builtins {
         }
 
         // push the unmatched characters following the last match
+        // Here, a surprising thing happens: we silently discard the original
+        // context. This is as intended, Nix does the same.
         ret.push_back(Value::from(&text[pos..]));
 
         Ok(Value::List(NixList::from(ret)))
@@ -1134,7 +1143,7 @@ mod pure_builtins {
                 span,
             )
             .await?;
-        Ok(Value::Integer(s.to_str()?.as_str().len() as i64))
+        Ok(Value::Integer(s.to_contextful_str()?.as_str().len() as i64))
     }
 
     #[builtin("sub")]