Set durabilities for low-durability fields on high-durability inputs (#12627)

This commit is contained in:
Micha Reiser 2024-08-02 19:42:34 +02:00 committed by GitHub
parent dfb08856eb
commit 12177a42e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 50 additions and 51 deletions

6
Cargo.lock generated
View file

@ -2739,7 +2739,7 @@ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]] [[package]]
name = "salsa" name = "salsa"
version = "0.18.0" 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 = [ dependencies = [
"arc-swap", "arc-swap",
"boomphf", "boomphf",
@ -2759,12 +2759,12 @@ dependencies = [
[[package]] [[package]]
name = "salsa-macro-rules" name = "salsa-macro-rules"
version = "0.1.0" 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]] [[package]]
name = "salsa-macros" name = "salsa-macros"
version = "0.18.0" 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 = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",

View file

@ -107,7 +107,7 @@ rand = { version = "0.8.5" }
rayon = { version = "1.10.0" } 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" }
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" } 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

@ -73,7 +73,8 @@ pub struct Workspace {
/// Setting the open files to a non-`None` value changes `check` to only check the /// Setting the open files to a non-`None` value changes `check` to only check the
/// open files rather than all files in the workspace. /// open files rather than all files in the workspace.
#[return_ref] #[return_ref]
open_file_set: Option<Arc<FxHashSet<File>>>, #[default]
open_fileset: Option<Arc<FxHashSet<File>>>,
/// The (first-party) packages in this workspace. /// The (first-party) packages in this workspace.
#[return_ref] #[return_ref]
@ -92,6 +93,7 @@ pub struct Package {
/// The files that are part of this package. /// The files that are part of this package.
#[return_ref] #[return_ref]
#[default]
file_set: PackageFiles, file_set: PackageFiles,
// TODO: Add the loaded settings. // TODO: Add the loaded settings.
} }
@ -105,8 +107,9 @@ impl Workspace {
packages.insert(package.root.clone(), Package::from_metadata(db, package)); packages.insert(package.root.clone(), Package::from_metadata(db, package));
} }
Workspace::builder(metadata.root, None, packages) Workspace::builder(metadata.root, packages)
.durability(Durability::MEDIUM) .durability(Durability::MEDIUM)
.open_fileset_durability(Durability::LOW)
.new(db) .new(db)
} }
@ -214,7 +217,7 @@ impl Workspace {
/// Returns the open files in the workspace or `None` if the entire workspace should be checked. /// 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<File>> { pub fn open_files(self, db: &dyn Db) -> Option<&FxHashSet<File>> {
self.open_file_set(db).as_deref() self.open_fileset(db).as_deref()
} }
/// Sets the open files in the workspace. /// 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. /// 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))] #[tracing::instrument(level = "debug", skip(self, db))]
pub fn set_open_files(self, db: &mut dyn Db, open_files: FxHashSet<File>) { pub fn set_open_files(self, db: &mut dyn Db, open_files: FxHashSet<File>) {
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. /// 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<File> { pub fn take_open_files(self, db: &mut dyn Db) -> FxHashSet<File> {
// Salsa will cancel any pending queries and remove its own reference to `open_files` // 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. // 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 { if let Some(open_files) = open_files {
Arc::try_unwrap(open_files).unwrap() Arc::try_unwrap(open_files).unwrap()
@ -309,8 +312,9 @@ impl Package {
} }
fn from_metadata(db: &dyn Db, metadata: PackageMetadata) -> Self { 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) .durability(Durability::MEDIUM)
.file_set_durability(Durability::LOW)
.new(db) .new(db)
} }

View file

@ -7,7 +7,7 @@
/// * The last modification time of the file. /// * The last modification time of the file.
/// * The hash of the file's content. /// * The hash of the file's content.
/// * The revision as it comes from an external system, for example the LSP. /// * 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); pub struct FileRevision(u128);
impl FileRevision { impl FileRevision {

View file

@ -91,27 +91,19 @@ impl Files {
.root(db, path) .root(db, path)
.map_or(Durability::default(), |root| root.durability(db)); .map_or(Durability::default(), |root| root.durability(db));
let (permissions, revision, status) = match metadata { let builder = File::builder(FilePath::System(absolute)).durability(durability);
Ok(metadata) if metadata.file_type().is_file() => (
metadata.permissions(), let builder = match metadata {
metadata.revision(), Ok(metadata) if metadata.file_type().is_file() => builder
FileStatus::Exists, .permissions(metadata.permissions())
), .revision(metadata.revision()),
Ok(metadata) if metadata.file_type().is_directory() => { 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( builder.new(db)
FilePath::System(absolute),
permissions,
revision,
status,
Count::default(),
)
.durability(durability)
.new(db)
}) })
} }
@ -139,13 +131,9 @@ impl Files {
Err(_) => return Err(FileError::NotFound), Err(_) => return Err(FileError::NotFound),
}; };
let file = File::builder( let file = File::builder(FilePath::Vendored(path.to_path_buf()))
FilePath::Vendored(path.to_path_buf()), .permissions(Some(0o444))
Some(0o444), .revision(metadata.revision())
metadata.revision(),
FileStatus::Exists,
Count::default(),
)
.durability(Durability::HIGH) .durability(Durability::HIGH)
.new(db); .new(db);
@ -170,14 +158,10 @@ impl Files {
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let metadata = db.system().virtual_path_metadata(path).ok()?; let metadata = db.system().virtual_path_metadata(path).ok()?;
let file = File::new( let file = File::builder(FilePath::SystemVirtual(path.to_path_buf()))
db, .revision(metadata.revision())
FilePath::SystemVirtual(path.to_path_buf()), .permissions(metadata.permissions())
metadata.permissions(), .new(db);
metadata.revision(),
FileStatus::Exists,
Count::default(),
);
entry.insert(file); 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 /// The unix permissions of the file. Only supported on unix systems. Always `None` on Windows
/// or when the file has been deleted. /// or when the file has been deleted.
#[default]
pub permissions: Option<u32>, pub permissions: Option<u32>,
/// The file revision. A file has changed if the revisions don't compare equal. /// The file revision. A file has changed if the revisions don't compare equal.
#[default]
pub revision: FileRevision, pub revision: FileRevision,
/// The status of the file. /// The status of the file.
/// ///
/// Salsa doesn't support deleting inputs. The only way to signal dependent queries that /// 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`. /// the file has been deleted is to change the status to `Deleted`.
#[default]
status: FileStatus, status: FileStatus,
/// Counter that counts the number of created file instances and active file instances. /// Counter that counts the number of created file instances and active file instances.
/// Only enabled in debug builds. /// Only enabled in debug builds.
#[allow(unused)] #[default]
count: Count<File>, count: Count<File>,
} }
@ -442,9 +429,10 @@ impl File {
// The types in here need to be public because they're salsa ingredients but we // 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. // don't want them to be publicly accessible. That's why we put them into a private module.
mod private { mod private {
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub enum FileStatus { pub enum FileStatus {
/// The file exists. /// The file exists.
#[default]
Exists, Exists,
/// The path isn't a file and instead points to a directory. /// The path isn't a file and instead points to a directory.

View file

@ -37,10 +37,7 @@ impl FileRoot {
} }
pub fn durability(self, db: &dyn Db) -> salsa::Durability { pub fn durability(self, db: &dyn Db) -> salsa::Durability {
match self.kind_at_time_of_creation(db) { self.kind_at_time_of_creation(db).durability()
FileRootKind::Workspace => salsa::Durability::LOW,
FileRootKind::LibrarySearchPath => salsa::Durability::HIGH,
}
} }
} }
@ -53,6 +50,15 @@ pub enum FileRootKind {
LibrarySearchPath, LibrarySearchPath,
} }
impl FileRootKind {
const fn durability(self) -> Durability {
match self {
FileRootKind::Workspace => Durability::LOW,
FileRootKind::LibrarySearchPath => Durability::HIGH,
}
}
}
#[derive(Default)] #[derive(Default)]
pub(super) struct FileRoots { pub(super) struct FileRoots {
by_path: matchit::Router<FileRoot>, by_path: matchit::Router<FileRoot>,
@ -86,6 +92,7 @@ impl FileRoots {
// Insert a new source root // Insert a new source root
let root = FileRoot::builder(path, kind, FileRevision::now()) let root = FileRoot::builder(path, kind, FileRevision::now())
.durability(Durability::HIGH) .durability(Durability::HIGH)
.revision_durability(kind.durability())
.new(db); .new(db);
// Insert a path that matches the root itself // Insert a path that matches the root itself