about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Hewitt <mail@davidhewitt.dev>2024-06-13 06:23:49 +0100
committerDavid Hewitt <mail@davidhewitt.dev>2024-06-13 06:32:05 +0100
commita29d99de3b7247930d8517dd27243ce4e15e0014 (patch)
treee5f8be86336c8f625d56eb36b4d4ca85e033e841
parent51ea7e831881446d513e6738fc15a49630ac4a72 (diff)
downloadrust-a29d99de3b7247930d8517dd27243ce4e15e0014.tar.gz
rust-a29d99de3b7247930d8517dd27243ce4e15e0014.zip
fix: add a breaker to avoid infinite loops from source root cycles
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index e8504979bed..ef890fa3e63 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -2531,6 +2531,7 @@ macro_rules! _impl_for_config_data {
                 #[allow(non_snake_case)]
                 $vis fn $field(&self, source_root: Option<SourceRootId>) -> &$ty {
                     let mut par: Option<SourceRootId> = source_root;
+                    let mut traversals = 0;
                     while let Some(source_root_id) = par {
                         par = self.source_root_parent_map.get(&source_root_id).copied();
                         if let Some((config, _)) = self.ratoml_files.get(&source_root_id) {
@@ -2538,6 +2539,14 @@ macro_rules! _impl_for_config_data {
                                 return value;
                             }
                         }
+                        // Prevent infinite loops caused by cycles by giving up when it's
+                        // clear that we must have either visited all source roots or
+                        // encountered a cycle.
+                        traversals += 1;
+                        if traversals >= self.source_root_parent_map.len() {
+                            // i.e. no source root contains the config we're looking for
+                            break;
+                        }
                     }
 
                     if let Some((root_path_ratoml, _)) = self.root_ratoml.as_ref() {