about summary refs log tree commit diff
path: root/tvix/cli
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-01-16T13·36+0300
committertazjin <tazjin@tvl.su>2023-01-17T10·45+0000
commit0cbdfffea22eb0bad38dad6f91f1c6f8e445651f (patch)
tree91a54705b65fe7313c4d0655ba2bfd7371bb1f60 /tvix/cli
parentbf6f6a0b3f41c480525846de233f57731c6d4ec7 (diff)
refactor(tvix/cli): consistently assert type unity in known_paths r/5677
No situation should be allowed in which a path is inserted into
known_paths with different types twice, which we previously enforced
only for some path types.

Change-Id: I8cb47d4b29c0aab3c58694f8b590e131deba7043
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7843
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/cli')
-rw-r--r--tvix/cli/src/known_paths.rs87
1 files changed, 41 insertions, 46 deletions
diff --git a/tvix/cli/src/known_paths.rs b/tvix/cli/src/known_paths.rs
index a5e95f5b5972..165bc3ea4161 100644
--- a/tvix/cli/src/known_paths.rs
+++ b/tvix/cli/src/known_paths.rs
@@ -50,39 +50,46 @@ impl Index<&str> for KnownPaths {
 }
 
 impl KnownPaths {
-    /// Mark a plain path as known.
-    pub fn plain<S: ToString>(&mut self, path: S) {
-        self.paths.insert(path.to_string(), PathType::Plain);
-    }
+    fn insert_path(&mut self, path: String, path_type: PathType) {
+        match self.paths.entry(path) {
+            hash_map::Entry::Vacant(entry) => {
+                entry.insert(path_type);
+            }
 
-    /// Mark a derivation as known.
-    pub fn drv<P: ToString, O: ToString>(&mut self, path: P, outputs: &[O]) {
-        match self.paths.entry(path.to_string()) {
             hash_map::Entry::Occupied(mut entry) => {
-                for output in outputs {
-                    match entry.get_mut() {
+                match (path_type, entry.get_mut()) {
+                    // These variant combinations require no "merging action".
+                    (PathType::Plain, PathType::Plain) => (),
+                    (PathType::Output { .. }, PathType::Output { .. }) => (),
+
+                    (
+                        PathType::Derivation { output_names: new },
                         PathType::Derivation {
-                            ref mut output_names,
-                        } => {
-                            output_names.insert(output.to_string());
-                        }
-
-                        // Branches like this explicitly panic right now to find odd
-                        // situations where something unexpected is done with the
-                        // same path being inserted twice as different types.
-                        _ => panic!(
-                            "bug: {} is already a known path, but not a derivation!",
-                            path.to_string()
-                        ),
+                            output_names: ref mut old,
+                        },
+                    ) => {
+                        old.extend(new);
                     }
-                }
-            }
 
-            hash_map::Entry::Vacant(entry) => {
-                let output_names = outputs.iter().map(|o| o.to_string()).collect();
-                entry.insert(PathType::Derivation { output_names });
+                    _ => panic!("path '{}' inserted twice with different types", entry.key()),
+                };
             }
-        }
+        };
+    }
+
+    /// Mark a plain path as known.
+    pub fn plain<S: ToString>(&mut self, path: S) {
+        self.insert_path(path.to_string(), PathType::Plain);
+    }
+
+    /// Mark a derivation as known.
+    pub fn drv<P: ToString, O: ToString>(&mut self, path: P, outputs: &[O]) {
+        self.insert_path(
+            path.to_string(),
+            PathType::Derivation {
+                output_names: outputs.into_iter().map(ToString::to_string).collect(),
+            },
+        );
     }
 
     /// Mark a derivation output path as known.
@@ -92,25 +99,13 @@ impl KnownPaths {
         name: N,
         drv_path: D,
     ) {
-        match self.paths.entry(output_path.to_string()) {
-            hash_map::Entry::Occupied(entry) => {
-                /* nothing to do, really! */
-                debug_assert!(
-                    *entry.get()
-                        == PathType::Output {
-                            name: name.to_string(),
-                            derivation: drv_path.to_string(),
-                        }
-                );
-            }
-
-            hash_map::Entry::Vacant(entry) => {
-                entry.insert(PathType::Output {
-                    name: name.to_string(),
-                    derivation: drv_path.to_string(),
-                });
-            }
-        }
+        self.insert_path(
+            output_path.to_string(),
+            PathType::Output {
+                name: name.to_string(),
+                derivation: drv_path.to_string(),
+            },
+        );
     }
 
     /// Create a reference scanner from the current set of known paths.