Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/base-db/src/lib.rs')
-rw-r--r--crates/base-db/src/lib.rs106
1 files changed, 41 insertions, 65 deletions
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index 0e411bcfae..24f6dd59a9 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -1,10 +1,16 @@
//! base_db defines basic database traits. The concrete DB is defined by ide.
+#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
+
+#[cfg(feature = "in-rust-tree")]
+extern crate rustc_driver as _;
+
pub use salsa;
pub use salsa_macros;
// FIXME: Rename this crate, base db is non descriptive
mod change;
+mod editioned_file_id;
mod input;
pub mod target;
@@ -17,6 +23,7 @@ use std::{
pub use crate::{
change::FileChange,
+ editioned_file_id::EditionedFileId,
input::{
BuiltCrateData, BuiltDependency, Crate, CrateBuilder, CrateBuilderId, CrateDataBuilder,
CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CratesIdMap, CratesMap,
@@ -29,7 +36,6 @@ pub use query_group::{self};
use rustc_hash::{FxHashSet, FxHasher};
use salsa::{Durability, Setter};
pub use semver::{BuildMetadata, Prerelease, Version, VersionReq};
-use span::Edition;
use syntax::{Parse, SyntaxError, ast};
use triomphe::Arc;
pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet};
@@ -58,6 +64,28 @@ macro_rules! impl_intern_key {
};
}
+/// # SAFETY
+///
+/// `old_pointer` must be valid for unique writes
+pub unsafe fn unsafe_update_eq<T>(old_pointer: *mut T, new_value: T) -> bool
+where
+ T: PartialEq,
+{
+ // SAFETY: Caller obligation
+ let old_ref: &mut T = unsafe { &mut *old_pointer };
+
+ if *old_ref != new_value {
+ *old_ref = new_value;
+ true
+ } else {
+ // Subtle but important: Eq impls can be buggy or define equality
+ // in surprising ways. If it says that the value has not changed,
+ // we do not modify the existing value, and thus do not have to
+ // update the revision, as downstream code will not see the new value.
+ false
+ }
+}
+
pub const DEFAULT_FILE_TEXT_LRU_CAP: u16 = 16;
pub const DEFAULT_PARSE_LRU_CAP: u16 = 128;
pub const DEFAULT_BORROWCK_LRU_CAP: u16 = 2024;
@@ -175,40 +203,20 @@ impl Files {
}
}
-#[salsa_macros::interned(no_lifetime, debug, constructor=from_span, revisions = usize::MAX)]
-#[derive(PartialOrd, Ord)]
-pub struct EditionedFileId {
- pub editioned_file_id: span::EditionedFileId,
+/// The set of roots for crates.io libraries.
+/// Files in libraries are assumed to never change.
+#[salsa::input(singleton, debug)]
+pub struct LibraryRoots {
+ #[returns(ref)]
+ pub roots: FxHashSet<SourceRootId>,
}
-impl EditionedFileId {
- // Salsa already uses the name `new`...
- #[inline]
- pub fn new(db: &dyn salsa::Database, file_id: FileId, edition: Edition) -> Self {
- EditionedFileId::from_span(db, span::EditionedFileId::new(file_id, edition))
- }
-
- #[inline]
- pub fn current_edition(db: &dyn salsa::Database, file_id: FileId) -> Self {
- EditionedFileId::new(db, file_id, Edition::CURRENT)
- }
-
- #[inline]
- pub fn file_id(self, db: &dyn salsa::Database) -> vfs::FileId {
- let id = self.editioned_file_id(db);
- id.file_id()
- }
-
- #[inline]
- pub fn unpack(self, db: &dyn salsa::Database) -> (vfs::FileId, span::Edition) {
- let id = self.editioned_file_id(db);
- (id.file_id(), id.edition())
- }
-
- #[inline]
- pub fn edition(self, db: &dyn SourceDatabase) -> Edition {
- self.editioned_file_id(db).edition()
- }
+/// The set of "local" (that is, from the current workspace) roots.
+/// Files in local roots are assumed to change frequently.
+#[salsa::input(singleton, debug)]
+pub struct LocalRoots {
+ #[returns(ref)]
+ pub roots: FxHashSet<SourceRootId>,
}
#[salsa_macros::input(debug)]
@@ -256,38 +264,6 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
/// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
#[salsa::input]
fn all_crates(&self) -> Arc<Box<[Crate]>>;
-
- /// Returns an iterator over all transitive dependencies of the given crate,
- /// including the crate itself.
- ///
- /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
- #[salsa::transparent]
- fn transitive_deps(&self, crate_id: Crate) -> FxHashSet<Crate>;
-
- /// Returns all transitive reverse dependencies of the given crate,
- /// including the crate itself.
- ///
- /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
- #[salsa::invoke(input::transitive_rev_deps)]
- #[salsa::transparent]
- fn transitive_rev_deps(&self, of: Crate) -> FxHashSet<Crate>;
-}
-
-pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Crate> {
- // There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible
- // and removing that is a bit difficult.
- let mut worklist = vec![crate_id];
- let mut deps = FxHashSet::default();
-
- while let Some(krate) = worklist.pop() {
- if !deps.insert(krate) {
- continue;
- }
-
- worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id));
- }
-
- deps
}
#[salsa_macros::db]