about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-12T15·52+0300
committertazjin <tazjin@tvl.su>2022-08-28T11·02+0000
commitde21d201ba7bca518ebbcfa091cdff94d7ea152e (patch)
treee2503b919bc723de9bcd9a92b393a34fe5ea72bd
parent6fe5e2d75257504f0321e2e98b6fb675b716fe25 (diff)
fix(tvix/eval): use path_clean instead of fs::canonicalize for paths r/4520
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>
-rw-r--r--tvix/eval/Cargo.lock7
-rw-r--r--tvix/eval/Cargo.toml1
-rw-r--r--tvix/eval/src/compiler.rs16
3 files changed, 14 insertions, 10 deletions
diff --git a/tvix/eval/Cargo.lock b/tvix/eval/Cargo.lock
index c25839fdbb..ecd0f05e40 100644
--- a/tvix/eval/Cargo.lock
+++ b/tvix/eval/Cargo.lock
@@ -464,6 +464,12 @@ 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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -834,6 +840,7 @@ version = "0.1.0"
 dependencies = [
  "criterion",
  "dirs",
+ "path-clean",
  "rnix",
  "rustyline",
  "smol_str",
diff --git a/tvix/eval/Cargo.toml b/tvix/eval/Cargo.toml
index b4cf604675..836b5deed1 100644
--- a/tvix/eval/Cargo.toml
+++ b/tvix/eval/Cargo.toml
@@ -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"
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 63a02f68c0..c840056b48 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -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));