fix(tvix/eval): don't thunk home relative paths

C++ Nix resolves home relative paths at [parse] time. This is not an
option for us, since it prevents being able to separate the compilation
and execution phase later (e.g. precompiled nix expressions). However, a
practical consequence of this is that paths expressions are always
literals (strict) and never thunks.

[parse]: 7066d21a0d/src/libexpr/parser.y (L518-L527)

Change-Id: Ie4b9dc68f62c86d6c7fd5f1c9460c850d97ed1ca
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7041
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
sterni 2023-06-13 22:26:15 +02:00
parent 0128323c55
commit 8e5551329a
2 changed files with 13 additions and 11 deletions

View file

@ -341,18 +341,17 @@ impl Compiler<'_> {
let path = if raw_path.starts_with('/') {
Path::new(&raw_path).to_owned()
} else if raw_path.starts_with('~') {
return self.thunk(slot, node, move |c, _| {
// We assume that home paths start with ~/ or fail to parse
// TODO: this should be checked using a parse-fail test.
debug_assert!(raw_path.len() > 2 && raw_path.starts_with("~/"));
// We assume that home paths start with ~/ or fail to parse
// TODO: this should be checked using a parse-fail test.
debug_assert!(raw_path.len() > 2 && raw_path.starts_with("~/"));
let home_relative_path = &raw_path[2..(raw_path.len())];
c.emit_constant(
Value::UnresolvedPath(Box::new(home_relative_path.into())),
node,
);
c.push_op(OpCode::OpResolveHomePath, node);
});
let home_relative_path = &raw_path[2..(raw_path.len())];
self.emit_constant(
Value::UnresolvedPath(Box::new(home_relative_path.into())),
node,
);
self.push_op(OpCode::OpResolveHomePath, node);
return;
} else if raw_path.starts_with('<') {
// TODO: decide what to do with findFile
if raw_path.len() == 2 {

View file

@ -154,6 +154,9 @@ compare_lazy_eval_tests! {
thunked_lambda_in_list("[ (x: x) ]");
thunked_function_application_in_list("[ (builtins.add 1 2) ]");
thunked_legacy_let_in_list("[ (let { foo = 12; body = foo; }) ]");
unthunked_relative_path("[ ./foo ]");
unthunked_home_relative_path("[ ~/foo ]");
unthunked_absolute_path("[ /foo ]");
unthunked_formals_fallback_literal("({ foo ? 12 }: [ foo ]) { }");
unthunked_formals_fallback_string_literal("({ foo ? \"wiggly\" }: [ foo ]) { }");