diff --git a/crates/ty_project/src/db.rs b/crates/ty_project/src/db.rs index 8e55f2fc7a..27be21058b 100644 --- a/crates/ty_project/src/db.rs +++ b/crates/ty_project/src/db.rs @@ -957,6 +957,7 @@ mod tests { use ruff_db::system::{DbWithWritableSystem as _, SystemPathBuf, TestSystem}; use ruff_db::testing::assert_function_query_was_not_run_by_name; use ruff_python_trivia::textwrap::dedent; + use salsa::plumbing::current_revision; use ty_module_resolver::list_modules; use ty_python_semantic::Db as _; @@ -996,6 +997,29 @@ mod tests { Ok(()) } + #[test] + fn unrelated_file_change_does_not_advance_revision() -> anyhow::Result<()> { + let system = TestSystem::default(); + let fs = system.memory_file_system().clone(); + fs.write_files_all([ + ("/project/main.py", ""), + ("/project/unrelated.log", "before"), + ])?; + let metadata = ProjectMetadata::new("test", SystemPathBuf::from("/project")); + let mut db = ProjectDatabase::fallible(metadata, system)?; + db.project().files(&db); + let revision = current_revision(&db); + + fs.write_file_all("/project/unrelated.log", "after")?; + db.apply_changes(&[ChangeEvent::file_content_changed(SystemPathBuf::from( + "/project/unrelated.log", + ))]); + + assert_eq!(current_revision(&db), revision); + + Ok(()) + } + #[test] fn changed_script_metadata_updates_import_resolution() -> anyhow::Result<()> { let system = TestSystem::default(); diff --git a/crates/ty_project/src/files.rs b/crates/ty_project/src/files.rs index b225872a6b..4e8118be8a 100644 --- a/crates/ty_project/src/files.rs +++ b/crates/ty_project/src/files.rs @@ -267,6 +267,7 @@ impl IndexedMut<'_> { pub(super) fn set_diagnostics(&mut self, diagnostics: Vec) { self.inner_mut().diagnostics = diagnostics; + self.did_change = true; } fn inner_mut(&mut self) -> &mut IndexedInner { diff --git a/crates/ty_project/src/lib.rs b/crates/ty_project/src/lib.rs index f6eb4362a3..513bfde3b5 100644 --- a/crates/ty_project/src/lib.rs +++ b/crates/ty_project/src/lib.rs @@ -766,6 +766,13 @@ impl Project { /// /// This is a no-op if the project files haven't been indexed yet. fn replace_index_diagnostics(self, db: &mut dyn Db, diagnostics: Vec) { + // Check before acquiring a mutable index, which cancels pending queries. + match self.file_set(db).get() { + Index::Lazy(_) => return, + Index::Indexed(index) if index.diagnostics() == diagnostics => return, + Index::Indexed(_) => {} + } + let Some(mut index) = IndexedFiles::indexed_mut(db, self) else { return; };