feat(tvix/eval): Allow adding strings to paths

Implement adding paths and strings via OpAdd. Since the nix rules are
quite obscure, I'm electing to test this one with an oracle test to
avoid the danger of getting the actual asserted result wrong.

Change-Id: Icdcca3690ca2e8459e386c1f29cc48eaaa39e9a3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6914
Autosubmit: grfn <grfn@gws.fyi>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Griffin Smith 2022-10-09 21:59:41 -04:00 committed by grfn
parent 66a35de3b6
commit 0e9f5d6890
5 changed files with 40 additions and 6 deletions

View file

@ -0,0 +1 @@
[ /bin /binbar /binbar /binbar /binbar /bin/bar /bin/bin ]

View file

@ -0,0 +1,9 @@
[
(/bin + "/")
(/bin + "bar")
(let name = "bar"; in /bin + name)
(let name = "bar"; in /bin + "${name}")
(let name = "bar"; in /bin + "/" + "${name}")
(let name = "bar"; in /bin + "/${name}")
(/bin + /bin)
]

View file

@ -383,6 +383,12 @@ impl From<String> for Value {
}
}
impl From<PathBuf> for Value {
fn from(path: PathBuf) -> Self {
Self::Path(path)
}
}
fn type_error(expected: &'static str, actual: &Value) -> ErrorKind {
ErrorKind::TypeError {
expected,

View file

@ -1,7 +1,9 @@
//! This module implements the virtual (or abstract) machine that runs
//! Tvix bytecode.
use std::{cell::RefMut, rc::Rc};
use std::{cell::RefMut, path::PathBuf, rc::Rc};
use path_clean::PathClean;
use crate::{
chunk::Chunk,
@ -347,10 +349,17 @@ impl<'o> VM<'o> {
let b = self.pop();
let a = self.pop();
let result = if let (Value::String(s1), Value::String(s2)) = (&a, &b) {
Value::String(s1.concat(s2))
} else {
fallible!(self, arithmetic_op!(&a, &b, +))
let result = match (&a, &b) {
(Value::String(s1), Value::String(s2)) => Value::String(s1.concat(s2)),
(Value::Path(p), v) => {
let mut path = p.to_string_lossy().into_owned();
path.push_str(
&v.coerce_to_string(CoercionKind::Weak, self)
.map_err(|ek| self.error(ek))?,
);
PathBuf::from(path).clean().into()
}
_ => fallible!(self, arithmetic_op!(&a, &b, +)),
};
self.push(result)

View file

@ -15,7 +15,7 @@ fn nix_eval(expr: &str) -> String {
let store_dir = TempDir::new("store-dir").unwrap();
let output = Command::new(nix_binary_path())
.args(["--eval", "-E"])
.args(["--eval", "--strict", "-E"])
.arg(format!("({expr})"))
.env(
"NIX_REMOTE",
@ -66,4 +66,13 @@ compare_eval_tests! {
literal_int("1");
add_ints("1 + 1");
add_lists("[1 2] ++ [3 4]");
add_paths(r#"[
(./. + "/")
(./foo + "bar")
(let name = "bar"; in ./foo + name)
(let name = "bar"; in ./foo + "${name}")
(let name = "bar"; in ./foo + "/" + "${name}")
(let name = "bar"; in ./foo + "/${name}")
(./. + ./.)
]"#);
}