diff options
author | Ryan Lahfa <tvl@lahfa.xyz> | 2023-12-25T23·40+0100 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2024-01-03T23·24+0000 |
commit | f44ac2a5940a93248ec9cff83856208bd629ae20 (patch) | |
tree | 6d34a4bb0fd5d6be826fded7e8542a79ad1d07a4 /tvix/eval/src | |
parent | 556e52c9cb8aa7b2af8bae75cd3365318e5d08c2 (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/src')
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 19 |
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")] |