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:
parent
6fe5e2d752
commit
de21d201ba
3 changed files with 14 additions and 10 deletions
7
tvix/eval/Cargo.lock
generated
7
tvix/eval/Cargo.lock
generated
|
@ -463,6 +463,12 @@ version = "11.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "path-clean"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.3"
|
||||
|
@ -834,6 +840,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"criterion",
|
||||
"dirs",
|
||||
"path-clean",
|
||||
"rnix",
|
||||
"rustyline",
|
||||
"smol_str",
|
||||
|
|
|
@ -10,6 +10,7 @@ rnix = "0.10.2"
|
|||
smol_str = "0.1"
|
||||
rustyline = "10.0.0"
|
||||
dirs = "4.0.0"
|
||||
path-clean = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.6"
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in a new issue