[ty] Update salsa (#17937)

## Summary

* Update salsa to pull in https://github.com/salsa-rs/salsa/pull/850.
* Some refactoring of salsa event callbacks in various `Db`'s due to
https://github.com/salsa-rs/salsa/pull/849

closes https://github.com/astral-sh/ty/issues/108

## Test Plan

Ran `cargo run --bin ty -- -vvv` on a test file to make sure that salsa
Events are still logged.
This commit is contained in:
David Peter 2025-05-08 12:02:53 +02:00 committed by GitHub
parent d566636ca5
commit 4f890b2867
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 96 additions and 113 deletions

6
Cargo.lock generated
View file

@ -3237,7 +3237,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]] [[package]]
name = "salsa" name = "salsa"
version = "0.21.1" version = "0.21.1"
source = "git+https://github.com/salsa-rs/salsa.git?rev=f78a641d2086695ac0ef96cbe915bf80b5a690f2#f78a641d2086695ac0ef96cbe915bf80b5a690f2" source = "git+https://github.com/salsa-rs/salsa.git?rev=2c869364a9592d06fdf45c422e1e4a7265a8fe8a#2c869364a9592d06fdf45c422e1e4a7265a8fe8a"
dependencies = [ dependencies = [
"boxcar", "boxcar",
"compact_str", "compact_str",
@ -3260,12 +3260,12 @@ dependencies = [
[[package]] [[package]]
name = "salsa-macro-rules" name = "salsa-macro-rules"
version = "0.21.1" version = "0.21.1"
source = "git+https://github.com/salsa-rs/salsa.git?rev=f78a641d2086695ac0ef96cbe915bf80b5a690f2#f78a641d2086695ac0ef96cbe915bf80b5a690f2" source = "git+https://github.com/salsa-rs/salsa.git?rev=2c869364a9592d06fdf45c422e1e4a7265a8fe8a#2c869364a9592d06fdf45c422e1e4a7265a8fe8a"
[[package]] [[package]]
name = "salsa-macros" name = "salsa-macros"
version = "0.21.1" version = "0.21.1"
source = "git+https://github.com/salsa-rs/salsa.git?rev=f78a641d2086695ac0ef96cbe915bf80b5a690f2#f78a641d2086695ac0ef96cbe915bf80b5a690f2" source = "git+https://github.com/salsa-rs/salsa.git?rev=2c869364a9592d06fdf45c422e1e4a7265a8fe8a#2c869364a9592d06fdf45c422e1e4a7265a8fe8a"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",

View file

@ -124,7 +124,7 @@ rayon = { version = "1.10.0" }
regex = { version = "1.10.2" } regex = { version = "1.10.2" }
rustc-hash = { version = "2.0.0" } rustc-hash = { version = "2.0.0" }
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml` # When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "f78a641d2086695ac0ef96cbe915bf80b5a690f2" } salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "2c869364a9592d06fdf45c422e1e4a7265a8fe8a" }
schemars = { version = "0.8.16" } schemars = { version = "0.8.16" }
seahash = { version = "4.1.0" } seahash = { version = "4.1.0" }
serde = { version = "1.0.197", features = ["derive"] } serde = { version = "1.0.197", features = ["derive"] }

View file

@ -61,7 +61,7 @@ pub fn max_parallelism() -> NonZeroUsize {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc; use std::sync::{Arc, Mutex};
use crate::files::Files; use crate::files::Files;
use crate::system::TestSystem; use crate::system::TestSystem;
@ -69,6 +69,8 @@ mod tests {
use crate::vendored::VendoredFileSystem; use crate::vendored::VendoredFileSystem;
use crate::Db; use crate::Db;
type Events = Arc<Mutex<Vec<salsa::Event>>>;
/// Database that can be used for testing. /// Database that can be used for testing.
/// ///
/// Uses an in memory filesystem and it stubs out the vendored files by default. /// Uses an in memory filesystem and it stubs out the vendored files by default.
@ -79,36 +81,37 @@ mod tests {
files: Files, files: Files,
system: TestSystem, system: TestSystem,
vendored: VendoredFileSystem, vendored: VendoredFileSystem,
events: Arc<std::sync::Mutex<Vec<salsa::Event>>>, events: Events,
} }
impl TestDb { impl TestDb {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
let events = Events::default();
Self { Self {
storage: salsa::Storage::default(), storage: salsa::Storage::new(Some(Box::new({
let events = events.clone();
move |event| {
tracing::trace!("event: {:?}", event);
let mut events = events.lock().unwrap();
events.push(event);
}
}))),
system: TestSystem::default(), system: TestSystem::default(),
vendored: VendoredFileSystem::default(), vendored: VendoredFileSystem::default(),
events: std::sync::Arc::default(), events,
files: Files::default(), files: Files::default(),
} }
} }
/// Empties the internal store of salsa events that have been emitted, /// Empties the internal store of salsa events that have been emitted,
/// and returns them as a `Vec` (equivalent to [`std::mem::take`]). /// and returns them as a `Vec` (equivalent to [`std::mem::take`]).
///
/// ## Panics
/// If there are pending database snapshots.
pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> { pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> {
let inner = Arc::get_mut(&mut self.events) let mut events = self.events.lock().unwrap();
.expect("expected no pending salsa database snapshots.");
std::mem::take(inner.get_mut().unwrap()) std::mem::take(&mut *events)
} }
/// Clears the emitted salsa events. /// Clears the emitted salsa events.
///
/// ## Panics
/// If there are pending database snapshots.
pub(crate) fn clear_salsa_events(&mut self) { pub(crate) fn clear_salsa_events(&mut self) {
self.take_salsa_events(); self.take_salsa_events();
} }
@ -148,12 +151,5 @@ mod tests {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for TestDb { impl salsa::Database for TestDb {}
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
let event = event();
tracing::trace!("event: {:?}", event);
let mut events = self.events.lock().unwrap();
events.push(event);
}
}
} }

View file

@ -98,6 +98,4 @@ impl Db for ModuleDb {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for ModuleDb { impl salsa::Database for ModuleDb {}
fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {}
}

View file

@ -6,7 +6,7 @@ pub trait Db: SemanticDb + Upcast<dyn SemanticDb> + Upcast<dyn SourceDb> {}
#[cfg(test)] #[cfg(test)]
pub(crate) mod tests { pub(crate) mod tests {
use std::sync::Arc; use std::sync::{Arc, Mutex};
use super::Db; use super::Db;
use ruff_db::files::{File, Files}; use ruff_db::files::{File, Files};
@ -16,6 +16,8 @@ pub(crate) mod tests {
use ty_python_semantic::lint::{LintRegistry, RuleSelection}; use ty_python_semantic::lint::{LintRegistry, RuleSelection};
use ty_python_semantic::{default_lint_registry, Db as SemanticDb, Program}; use ty_python_semantic::{default_lint_registry, Db as SemanticDb, Program};
type Events = Arc<Mutex<Vec<salsa::Event>>>;
#[salsa::db] #[salsa::db]
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct TestDb { pub(crate) struct TestDb {
@ -23,31 +25,35 @@ pub(crate) mod tests {
files: Files, files: Files,
system: TestSystem, system: TestSystem,
vendored: VendoredFileSystem, vendored: VendoredFileSystem,
events: Arc<std::sync::Mutex<Vec<salsa::Event>>>, events: Events,
rule_selection: Arc<RuleSelection>, rule_selection: Arc<RuleSelection>,
} }
#[expect(dead_code)] #[expect(dead_code)]
impl TestDb { impl TestDb {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
let events = Events::default();
Self { Self {
storage: salsa::Storage::default(), storage: salsa::Storage::new(Some(Box::new({
let events = events.clone();
move |event| {
tracing::trace!("event: {event:?}");
let mut events = events.lock().unwrap();
events.push(event);
}
}))),
system: TestSystem::default(), system: TestSystem::default(),
vendored: ty_vendored::file_system().clone(), vendored: ty_vendored::file_system().clone(),
events: Arc::default(), events,
files: Files::default(), files: Files::default(),
rule_selection: Arc::new(RuleSelection::from_registry(default_lint_registry())), rule_selection: Arc::new(RuleSelection::from_registry(default_lint_registry())),
} }
} }
/// Takes the salsa events. /// Takes the salsa events.
///
/// ## Panics
/// If there are any pending salsa snapshots.
pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> { pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> {
let inner = Arc::get_mut(&mut self.events).expect("no pending salsa snapshots"); let mut events = self.events.lock().unwrap();
let events = inner.get_mut().unwrap();
std::mem::take(&mut *events) std::mem::take(&mut *events)
} }
@ -127,12 +133,5 @@ pub(crate) mod tests {
impl Db for TestDb {} impl Db for TestDb {}
#[salsa::db] #[salsa::db]
impl salsa::Database for TestDb { impl salsa::Database for TestDb {}
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
let event = event();
tracing::trace!("event: {event:?}");
let mut events = self.events.lock().unwrap();
events.push(event);
}
}
} }

View file

@ -37,7 +37,19 @@ impl ProjectDatabase {
{ {
let mut db = Self { let mut db = Self {
project: None, project: None,
storage: salsa::Storage::default(), storage: salsa::Storage::new(if tracing::enabled!(tracing::Level::TRACE) {
Some(Box::new({
move |event: Event| {
if matches!(event.kind, salsa::EventKind::WillCheckCancellation) {
return;
}
tracing::trace!("Salsa event: {event:?}");
}
}))
} else {
None
}),
files: Files::default(), files: Files::default(),
system: Arc::new(system), system: Arc::new(system),
}; };
@ -156,20 +168,7 @@ impl SourceDb for ProjectDatabase {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for ProjectDatabase { impl salsa::Database for ProjectDatabase {}
fn salsa_event(&self, event: &dyn Fn() -> Event) {
if !tracing::enabled!(tracing::Level::TRACE) {
return;
}
let event = event();
if matches!(event.kind, salsa::EventKind::WillCheckCancellation) {
return;
}
tracing::trace!("Salsa event: {event:?}");
}
}
#[salsa::db] #[salsa::db]
impl Db for ProjectDatabase { impl Db for ProjectDatabase {
@ -206,9 +205,7 @@ mod format {
#[cfg(test)] #[cfg(test)]
pub(crate) mod tests { pub(crate) mod tests {
use std::sync::Arc; use std::sync::{Arc, Mutex};
use salsa::Event;
use ruff_db::files::Files; use ruff_db::files::Files;
use ruff_db::system::{DbWithTestSystem, System, TestSystem}; use ruff_db::system::{DbWithTestSystem, System, TestSystem};
@ -221,11 +218,13 @@ pub(crate) mod tests {
use crate::DEFAULT_LINT_REGISTRY; use crate::DEFAULT_LINT_REGISTRY;
use crate::{Project, ProjectMetadata}; use crate::{Project, ProjectMetadata};
type Events = Arc<Mutex<Vec<salsa::Event>>>;
#[salsa::db] #[salsa::db]
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct TestDb { pub(crate) struct TestDb {
storage: salsa::Storage<Self>, storage: salsa::Storage<Self>,
events: Arc<std::sync::Mutex<Vec<Event>>>, events: Events,
files: Files, files: Files,
system: TestSystem, system: TestSystem,
vendored: VendoredFileSystem, vendored: VendoredFileSystem,
@ -234,12 +233,19 @@ pub(crate) mod tests {
impl TestDb { impl TestDb {
pub(crate) fn new(project: ProjectMetadata) -> Self { pub(crate) fn new(project: ProjectMetadata) -> Self {
let events = Events::default();
let mut db = Self { let mut db = Self {
storage: salsa::Storage::default(), storage: salsa::Storage::new(Some(Box::new({
let events = events.clone();
move |event| {
let mut events = events.lock().unwrap();
events.push(event);
}
}))),
system: TestSystem::default(), system: TestSystem::default(),
vendored: ty_vendored::file_system().clone(), vendored: ty_vendored::file_system().clone(),
files: Files::default(), files: Files::default(),
events: Arc::default(), events,
project: None, project: None,
}; };
@ -251,13 +257,9 @@ pub(crate) mod tests {
impl TestDb { impl TestDb {
/// Takes the salsa events. /// Takes the salsa events.
///
/// ## Panics
/// If there are any pending salsa snapshots.
pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> { pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> {
let inner = Arc::get_mut(&mut self.events).expect("no pending salsa snapshots"); let mut events = self.events.lock().unwrap();
let events = inner.get_mut().unwrap();
std::mem::take(&mut *events) std::mem::take(&mut *events)
} }
} }
@ -332,10 +334,5 @@ pub(crate) mod tests {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for TestDb { impl salsa::Database for TestDb {}
fn salsa_event(&self, event: &dyn Fn() -> Event) {
let mut events = self.events.lock().unwrap();
events.push(event());
}
}
} }

View file

@ -16,7 +16,7 @@ pub trait Db: SourceDb + Upcast<dyn SourceDb> {
#[cfg(test)] #[cfg(test)]
pub(crate) mod tests { pub(crate) mod tests {
use std::sync::Arc; use std::sync::{Arc, Mutex};
use crate::program::{Program, SearchPathSettings}; use crate::program::{Program, SearchPathSettings};
use crate::{default_lint_registry, ProgramSettings, PythonPlatform}; use crate::{default_lint_registry, ProgramSettings, PythonPlatform};
@ -32,6 +32,8 @@ pub(crate) mod tests {
use ruff_db::{Db as SourceDb, Upcast}; use ruff_db::{Db as SourceDb, Upcast};
use ruff_python_ast::PythonVersion; use ruff_python_ast::PythonVersion;
type Events = Arc<Mutex<Vec<salsa::Event>>>;
#[salsa::db] #[salsa::db]
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct TestDb { pub(crate) struct TestDb {
@ -39,30 +41,34 @@ pub(crate) mod tests {
files: Files, files: Files,
system: TestSystem, system: TestSystem,
vendored: VendoredFileSystem, vendored: VendoredFileSystem,
events: Arc<std::sync::Mutex<Vec<salsa::Event>>>, events: Events,
rule_selection: Arc<RuleSelection>, rule_selection: Arc<RuleSelection>,
} }
impl TestDb { impl TestDb {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
let events = Events::default();
Self { Self {
storage: salsa::Storage::default(), storage: salsa::Storage::new(Some(Box::new({
let events = events.clone();
move |event| {
tracing::trace!("event: {event:?}");
let mut events = events.lock().unwrap();
events.push(event);
}
}))),
system: TestSystem::default(), system: TestSystem::default(),
vendored: ty_vendored::file_system().clone(), vendored: ty_vendored::file_system().clone(),
events: Arc::default(), events,
files: Files::default(), files: Files::default(),
rule_selection: Arc::new(RuleSelection::from_registry(default_lint_registry())), rule_selection: Arc::new(RuleSelection::from_registry(default_lint_registry())),
} }
} }
/// Takes the salsa events. /// Takes the salsa events.
///
/// ## Panics
/// If there are any pending salsa snapshots.
pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> { pub(crate) fn take_salsa_events(&mut self) -> Vec<salsa::Event> {
let inner = Arc::get_mut(&mut self.events).expect("no pending salsa snapshots"); let mut events = self.events.lock().unwrap();
let events = inner.get_mut().unwrap();
std::mem::take(&mut *events) std::mem::take(&mut *events)
} }
@ -129,14 +135,7 @@ pub(crate) mod tests {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for TestDb { impl salsa::Database for TestDb {}
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
let event = event();
tracing::trace!("event: {event:?}");
let mut events = self.events.lock().unwrap();
events.push(event);
}
}
pub(crate) struct TestDbBuilder<'a> { pub(crate) struct TestDbBuilder<'a> {
/// Target Python version /// Target Python version

View file

@ -29,7 +29,11 @@ impl Db {
Self { Self {
system: MdtestSystem::in_memory(), system: MdtestSystem::in_memory(),
storage: salsa::Storage::default(), storage: salsa::Storage::new(Some(Box::new({
move |event| {
tracing::trace!("event: {:?}", event);
}
}))),
vendored: ty_vendored::file_system().clone(), vendored: ty_vendored::file_system().clone(),
files: Files::default(), files: Files::default(),
rule_selection: Arc::new(rule_selection), rule_selection: Arc::new(rule_selection),
@ -95,12 +99,7 @@ impl SemanticDb for Db {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for Db { impl salsa::Database for Db {}
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
let event = event();
tracing::trace!("event: {:?}", event);
}
}
impl DbWithWritableSystem for Db { impl DbWithWritableSystem for Db {
type System = MdtestSystem; type System = MdtestSystem;

View file

@ -30,7 +30,7 @@ ty_python_semantic = { path = "../crates/ty_python_semantic" }
ty_vendored = { path = "../crates/ty_vendored" } ty_vendored = { path = "../crates/ty_vendored" }
libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer", default-features = false } libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer", default-features = false }
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "f78a641d2086695ac0ef96cbe915bf80b5a690f2" } salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "2c869364a9592d06fdf45c422e1e4a7265a8fe8a" }
similar = { version = "2.5.0" } similar = { version = "2.5.0" }
tracing = { version = "0.1.40" } tracing = { version = "0.1.40" }

View file

@ -32,17 +32,19 @@ struct TestDb {
files: Files, files: Files,
system: TestSystem, system: TestSystem,
vendored: VendoredFileSystem, vendored: VendoredFileSystem,
events: Arc<Mutex<Vec<salsa::Event>>>,
rule_selection: Arc<RuleSelection>, rule_selection: Arc<RuleSelection>,
} }
impl TestDb { impl TestDb {
fn new() -> Self { fn new() -> Self {
Self { Self {
storage: salsa::Storage::default(), storage: salsa::Storage::new(Some(Box::new({
move |event| {
tracing::trace!("event: {:?}", event);
}
}))),
system: TestSystem::default(), system: TestSystem::default(),
vendored: ty_vendored::file_system().clone(), vendored: ty_vendored::file_system().clone(),
events: Arc::default(),
files: Files::default(), files: Files::default(),
rule_selection: RuleSelection::from_registry(default_lint_registry()).into(), rule_selection: RuleSelection::from_registry(default_lint_registry()).into(),
} }
@ -103,14 +105,7 @@ impl SemanticDb for TestDb {
} }
#[salsa::db] #[salsa::db]
impl salsa::Database for TestDb { impl salsa::Database for TestDb {}
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
let event = event();
tracing::trace!("event: {:?}", event);
let mut events = self.events.lock().unwrap();
events.push(event);
}
}
fn setup_db() -> TestDb { fn setup_db() -> TestDb {
let db = TestDb::new(); let db = TestDb::new();