]> git.lizzy.rs Git - rust.git/commitdiff
not visit the same crateId only once
authorgfreezy <gfreezy@gmail.com>
Sat, 22 Dec 2018 07:30:58 +0000 (15:30 +0800)
committergfreezy <gfreezy@gmail.com>
Sat, 22 Dec 2018 07:30:58 +0000 (15:30 +0800)
crates/ra_db/src/input.rs

index ee4de6fa974578bb1dd2cb1240d56246bff773e0..e9a991a574819de97f45b70b49bff27933f61b82 100644 (file)
@@ -12,6 +12,7 @@
 use salsa;
 
 use ra_syntax::SmolStr;
+use rustc_hash::FxHashSet;
 
 /// `FileId` is an integer which uniquely identifies a file. File paths are
 /// messy and system-dependent, so most of the code should work directly with
@@ -94,8 +95,9 @@ pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId {
         crate_id
     }
     pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) {
-        if self.dfs_find(from, to) {
-           panic!("Cycle dependencies found.")
+        let mut visited = FxHashSet::default();
+        if self.dfs_find(from, to, &mut visited) {
+            panic!("Cycle dependencies found.")
         }
         self.arena.get_mut(&from).unwrap().add_dep(name, to)
     }
@@ -112,35 +114,36 @@ pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
     pub fn dependencies<'a>(
         &'a self,
         crate_id: CrateId,
-    ) -> impl Iterator<Item=&'a Dependency> + 'a {
+    ) -> impl Iterator<Item = &'a Dependency> + 'a {
         self.arena[&crate_id].dependencies.iter()
     }
-    fn dfs_find(&self, target: CrateId, from: CrateId) -> bool {
+    fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool {
+        if visited.contains(&from) {
+            return false;
+        }
         for dep in self.dependencies(from) {
             let crate_id = dep.crate_id();
             if crate_id == target {
                 return true;
             }
-            if self.arena.contains_key(&crate_id) {
-                if self.dfs_find(target, crate_id) {
-                    return true;
-                }
+
+            if self.dfs_find(target, crate_id, visited) {
+                return true;
             }
         }
+        visited.insert(from);
         return false;
     }
 }
 
-
 #[cfg(test)]
 mod tests {
     use super::{CrateGraph, FxHashMap, FileId, SmolStr};
+
     #[test]
     #[should_panic]
     fn it_should_painc_because_of_cycle_dependencies() {
-        let mut graph = CrateGraph {
-            arena: FxHashMap::default()
-        };
+        let mut graph = CrateGraph::default();
         let crate1 = graph.add_crate_root(FileId(1u32));
         let crate2 = graph.add_crate_root(FileId(2u32));
         let crate3 = graph.add_crate_root(FileId(3u32));
@@ -152,7 +155,7 @@ fn it_should_painc_because_of_cycle_dependencies() {
     #[test]
     fn it_works() {
         let mut graph = CrateGraph {
-            arena: FxHashMap::default()
+            arena: FxHashMap::default(),
         };
         let crate1 = graph.add_crate_root(FileId(1u32));
         let crate2 = graph.add_crate_root(FileId(2u32));
@@ -162,7 +165,6 @@ fn it_works() {
     }
 }
 
-
 salsa::query_group! {
     pub trait FilesDatabase: salsa::Database {
         /// Text of the file.