fix(tvix/eval): use path_clean instead of fs::canonicalize for paths

Canonicalisation performs much more functionality than what C++ Nix
implements for paths, and causes some undesirable behaviour (e.g.
handling non-existant files becomes difficult, but should be possible
in literals).

Instead, the path_clean crate provides a pure normalisation method.

There is an intention to add this to Rust itself:
https://github.com/rust-lang/rfcs/issues/2208

Change-Id: I775d238136db0a52cf6b12a68985833c8fb32882
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6186
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-08-12 18:52:48 +03:00 committed by tazjin
parent 6fe5e2d752
commit de21d201ba
3 changed files with 14 additions and 10 deletions

View file

@ -13,6 +13,9 @@
//! the code in this module, `debug_assert!` has been used to catch
//! mistakes early during development.
use path_clean::PathClean;
use rnix;
use rnix::types::{BinOpKind, EntryHolder, TokenWrapper, TypedNode, Wrapper};
use std::path::{Path, PathBuf};
use crate::chunk::Chunk;
@ -21,9 +24,6 @@ use crate::opcode::{CodeIdx, OpCode};
use crate::value::Value;
use crate::warnings::{EvalWarning, WarningKind};
use rnix;
use rnix::types::{BinOpKind, EntryHolder, TokenWrapper, TypedNode, Wrapper};
/// Represents the result of compiling a piece of Nix code. If
/// compilation was successful, the resulting bytecode can be passed
/// to the VM.
@ -162,8 +162,6 @@ impl Compiler {
}
fn compile_path(&mut self, anchor: rnix::value::Anchor, path: String) -> EvalResult<()> {
// TODO(tazjin): C++ Nix does not resolve symlinks, but `fs::canonicalize` does.
let path = match anchor {
rnix::value::Anchor::Absolute => Path::new(&path).to_owned(),
@ -189,11 +187,9 @@ impl Compiler {
rnix::value::Anchor::Store => todo!("resolve <...> lookups at runtime"),
};
let value =
Value::Path(path.canonicalize().map_err(|e| {
Error::PathResolution(format!("failed to canonicalise path: {}", e))
})?);
// TODO: Use https://github.com/rust-lang/rfcs/issues/2208
// once it is available
let value = Value::Path(path.clean());
let idx = self.chunk.push_constant(value);
self.chunk.push_op(OpCode::OpConstant(idx));