diff --git a/Cargo.lock b/Cargo.lock index 6f4fe43f9a..2898f7af2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2739,7 +2739,7 @@ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "salsa" version = "0.18.0" -source = "git+https://github.com/MichaReiser/salsa.git?rev=0cae5c52a3240172ef0be5c9d19e63448c53397c#0cae5c52a3240172ef0be5c9d19e63448c53397c" +source = "git+https://github.com/MichaReiser/salsa.git?rev=635e23943c095077c4a423488ac829b4ae0bfa77#635e23943c095077c4a423488ac829b4ae0bfa77" dependencies = [ "arc-swap", "boomphf", @@ -2759,12 +2759,12 @@ dependencies = [ [[package]] name = "salsa-macro-rules" version = "0.1.0" -source = "git+https://github.com/MichaReiser/salsa.git?rev=0cae5c52a3240172ef0be5c9d19e63448c53397c#0cae5c52a3240172ef0be5c9d19e63448c53397c" +source = "git+https://github.com/MichaReiser/salsa.git?rev=635e23943c095077c4a423488ac829b4ae0bfa77#635e23943c095077c4a423488ac829b4ae0bfa77" [[package]] name = "salsa-macros" version = "0.18.0" -source = "git+https://github.com/MichaReiser/salsa.git?rev=0cae5c52a3240172ef0be5c9d19e63448c53397c#0cae5c52a3240172ef0be5c9d19e63448c53397c" +source = "git+https://github.com/MichaReiser/salsa.git?rev=635e23943c095077c4a423488ac829b4ae0bfa77#635e23943c095077c4a423488ac829b4ae0bfa77" dependencies = [ "heck", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index a6bfb5d5e7..92ad326b5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,7 @@ rand = { version = "0.8.5" } rayon = { version = "1.10.0" } regex = { version = "1.10.2" } rustc-hash = { version = "2.0.0" } -salsa = { git = "https://github.com/MichaReiser/salsa.git", rev = "0cae5c52a3240172ef0be5c9d19e63448c53397c" } +salsa = { git = "https://github.com/MichaReiser/salsa.git", rev = "635e23943c095077c4a423488ac829b4ae0bfa77" } schemars = { version = "0.8.16" } seahash = { version = "4.1.0" } serde = { version = "1.0.197", features = ["derive"] } diff --git a/crates/red_knot_workspace/src/workspace.rs b/crates/red_knot_workspace/src/workspace.rs index d262ef39b0..f07a55ee11 100644 --- a/crates/red_knot_workspace/src/workspace.rs +++ b/crates/red_knot_workspace/src/workspace.rs @@ -73,7 +73,8 @@ pub struct Workspace { /// Setting the open files to a non-`None` value changes `check` to only check the /// open files rather than all files in the workspace. #[return_ref] - open_file_set: Option>>, + #[default] + open_fileset: Option>>, /// The (first-party) packages in this workspace. #[return_ref] @@ -92,6 +93,7 @@ pub struct Package { /// The files that are part of this package. #[return_ref] + #[default] file_set: PackageFiles, // TODO: Add the loaded settings. } @@ -105,8 +107,9 @@ impl Workspace { packages.insert(package.root.clone(), Package::from_metadata(db, package)); } - Workspace::builder(metadata.root, None, packages) + Workspace::builder(metadata.root, packages) .durability(Durability::MEDIUM) + .open_fileset_durability(Durability::LOW) .new(db) } @@ -214,7 +217,7 @@ impl Workspace { /// Returns the open files in the workspace or `None` if the entire workspace should be checked. pub fn open_files(self, db: &dyn Db) -> Option<&FxHashSet> { - self.open_file_set(db).as_deref() + self.open_fileset(db).as_deref() } /// Sets the open files in the workspace. @@ -222,7 +225,7 @@ impl Workspace { /// This changes the behavior of `check` to only check the open files rather than all files in the workspace. #[tracing::instrument(level = "debug", skip(self, db))] pub fn set_open_files(self, db: &mut dyn Db, open_files: FxHashSet) { - self.set_open_file_set(db).to(Some(Arc::new(open_files))); + self.set_open_fileset(db).to(Some(Arc::new(open_files))); } /// This takes the open files from the workspace and returns them. @@ -231,7 +234,7 @@ impl Workspace { pub fn take_open_files(self, db: &mut dyn Db) -> FxHashSet { // Salsa will cancel any pending queries and remove its own reference to `open_files` // so that the reference counter to `open_files` now drops to 1. - let open_files = self.set_open_file_set(db).to(None); + let open_files = self.set_open_fileset(db).to(None); if let Some(open_files) = open_files { Arc::try_unwrap(open_files).unwrap() @@ -309,8 +312,9 @@ impl Package { } fn from_metadata(db: &dyn Db, metadata: PackageMetadata) -> Self { - Self::builder(metadata.name, metadata.root, PackageFiles::default()) + Self::builder(metadata.name, metadata.root) .durability(Durability::MEDIUM) + .file_set_durability(Durability::LOW) .new(db) } diff --git a/crates/ruff_db/src/file_revision.rs b/crates/ruff_db/src/file_revision.rs index a12d91a5b3..35b27aa9d2 100644 --- a/crates/ruff_db/src/file_revision.rs +++ b/crates/ruff_db/src/file_revision.rs @@ -7,7 +7,7 @@ /// * The last modification time of the file. /// * The hash of the file's content. /// * The revision as it comes from an external system, for example the LSP. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] pub struct FileRevision(u128); impl FileRevision { diff --git a/crates/ruff_db/src/files.rs b/crates/ruff_db/src/files.rs index 2ad371542b..ab0e27d2dc 100644 --- a/crates/ruff_db/src/files.rs +++ b/crates/ruff_db/src/files.rs @@ -91,27 +91,19 @@ impl Files { .root(db, path) .map_or(Durability::default(), |root| root.durability(db)); - let (permissions, revision, status) = match metadata { - Ok(metadata) if metadata.file_type().is_file() => ( - metadata.permissions(), - metadata.revision(), - FileStatus::Exists, - ), + let builder = File::builder(FilePath::System(absolute)).durability(durability); + + let builder = match metadata { + Ok(metadata) if metadata.file_type().is_file() => builder + .permissions(metadata.permissions()) + .revision(metadata.revision()), Ok(metadata) if metadata.file_type().is_directory() => { - (None, FileRevision::zero(), FileStatus::IsADirectory) + builder.status(FileStatus::IsADirectory) } - _ => (None, FileRevision::zero(), FileStatus::NotFound), + _ => builder.status(FileStatus::NotFound), }; - File::builder( - FilePath::System(absolute), - permissions, - revision, - status, - Count::default(), - ) - .durability(durability) - .new(db) + builder.new(db) }) } @@ -139,15 +131,11 @@ impl Files { Err(_) => return Err(FileError::NotFound), }; - let file = File::builder( - FilePath::Vendored(path.to_path_buf()), - Some(0o444), - metadata.revision(), - FileStatus::Exists, - Count::default(), - ) - .durability(Durability::HIGH) - .new(db); + let file = File::builder(FilePath::Vendored(path.to_path_buf())) + .permissions(Some(0o444)) + .revision(metadata.revision()) + .durability(Durability::HIGH) + .new(db); entry.insert(file); @@ -170,14 +158,10 @@ impl Files { Entry::Vacant(entry) => { let metadata = db.system().virtual_path_metadata(path).ok()?; - let file = File::new( - db, - FilePath::SystemVirtual(path.to_path_buf()), - metadata.permissions(), - metadata.revision(), - FileStatus::Exists, - Count::default(), - ); + let file = File::builder(FilePath::SystemVirtual(path.to_path_buf())) + .revision(metadata.revision()) + .permissions(metadata.permissions()) + .new(db); entry.insert(file); @@ -290,20 +274,23 @@ pub struct File { /// The unix permissions of the file. Only supported on unix systems. Always `None` on Windows /// or when the file has been deleted. + #[default] pub permissions: Option, /// The file revision. A file has changed if the revisions don't compare equal. + #[default] pub revision: FileRevision, /// The status of the file. /// /// Salsa doesn't support deleting inputs. The only way to signal dependent queries that /// the file has been deleted is to change the status to `Deleted`. + #[default] status: FileStatus, /// Counter that counts the number of created file instances and active file instances. /// Only enabled in debug builds. - #[allow(unused)] + #[default] count: Count, } @@ -442,9 +429,10 @@ impl File { // The types in here need to be public because they're salsa ingredients but we // don't want them to be publicly accessible. That's why we put them into a private module. mod private { - #[derive(Copy, Clone, Debug, Eq, PartialEq)] + #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] pub enum FileStatus { /// The file exists. + #[default] Exists, /// The path isn't a file and instead points to a directory. diff --git a/crates/ruff_db/src/files/file_root.rs b/crates/ruff_db/src/files/file_root.rs index 6375655edd..c12a9e0d0c 100644 --- a/crates/ruff_db/src/files/file_root.rs +++ b/crates/ruff_db/src/files/file_root.rs @@ -37,10 +37,7 @@ impl FileRoot { } pub fn durability(self, db: &dyn Db) -> salsa::Durability { - match self.kind_at_time_of_creation(db) { - FileRootKind::Workspace => salsa::Durability::LOW, - FileRootKind::LibrarySearchPath => salsa::Durability::HIGH, - } + self.kind_at_time_of_creation(db).durability() } } @@ -53,6 +50,15 @@ pub enum FileRootKind { LibrarySearchPath, } +impl FileRootKind { + const fn durability(self) -> Durability { + match self { + FileRootKind::Workspace => Durability::LOW, + FileRootKind::LibrarySearchPath => Durability::HIGH, + } + } +} + #[derive(Default)] pub(super) struct FileRoots { by_path: matchit::Router, @@ -86,6 +92,7 @@ impl FileRoots { // Insert a new source root let root = FileRoot::builder(path, kind, FileRevision::now()) .durability(Durability::HIGH) + .revision_durability(kind.durability()) .new(db); // Insert a path that matches the root itself