feat(tvix/eval): context-aware substring

`substring` has a very funny behavior when it comes to empty strings,
it propagates the context too, this is used in nixpkgs to attach context
to strings without using any builtin: `lib.addContextFrom`.

Change-Id: Id655356799b3485f7519b3d1914c630f9d8416c3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10448
Autosubmit: raitobezarius <tvl@lahfa.xyz>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Ryan Lahfa 2023-12-27 18:13:27 +01:00 committed by clbot
parent 375f7eaa59
commit 7dcb37fc52

View file

@ -1081,7 +1081,7 @@ mod pure_builtins {
if x.is_catchable() {
return Ok(x);
}
let x = x.to_str()?;
let x = x.to_contextful_str()?;
if beg < 0 {
return Err(ErrorKind::IndexOutOfBounds { index: beg });
@ -1092,7 +1092,7 @@ mod pure_builtins {
// non-negative when the starting index is GTE the
// string's length.
if beg >= x.as_str().len() {
return Ok(Value::String("".into()));
return Ok(Value::String(NixString::new_inherit_context_from(&x, "")));
}
let end = if len < 0 {
@ -1101,7 +1101,10 @@ mod pure_builtins {
cmp::min(beg + (len as usize), x.as_str().len())
};
Ok(Value::String(x.as_bytes()[beg..end].try_into()?))
Ok(Value::String(NixString::new_inherit_context_from(
&x,
&x[beg..end],
)))
}
#[builtin("tail")]