]> git.lizzy.rs Git - rust.git/blobdiff - crates/rust-analyzer/src/global_state.rs
internal: prepare to track changes to mem_docs
[rust.git] / crates / rust-analyzer / src / global_state.rs
index 583900cfeef2becc62209e7da78ed97f3090c52e..b21fff7071a961b20ca0b25871a32fb9199732b7 100644 (file)
@@ -8,11 +8,11 @@
 use crossbeam_channel::{unbounded, Receiver, Sender};
 use flycheck::FlycheckHandle;
 use ide::{Analysis, AnalysisHost, Cancellable, Change, FileId};
-use ide_db::base_db::{CrateId, VfsPath};
+use ide_db::base_db::CrateId;
 use lsp_types::{SemanticTokens, Url};
 use parking_lot::{Mutex, RwLock};
 use project_model::{
-    BuildDataCollector, BuildDataResult, CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target,
+    CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target, WorkspaceBuildScripts,
 };
 use rustc_hash::FxHashMap;
 use vfs::AnchoredPathBuf;
 use crate::{
     config::Config,
     diagnostics::{CheckFixes, DiagnosticCollection},
-    document::DocumentData,
     from_proto,
     line_index::{LineEndings, LineIndex},
     lsp_ext,
     main_loop::Task,
+    mem_docs::MemDocs,
     op_queue::OpQueue,
     reload::SourceRootConfig,
     request_metrics::{LatestRequests, RequestMetrics},
@@ -57,7 +57,7 @@ pub(crate) struct GlobalState {
     pub(crate) config: Arc<Config>,
     pub(crate) analysis_host: AnalysisHost,
     pub(crate) diagnostics: DiagnosticCollection,
-    pub(crate) mem_docs: FxHashMap<VfsPath, DocumentData>,
+    pub(crate) mem_docs: MemDocs,
     pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
     pub(crate) shutdown_requested: bool,
     pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
@@ -74,17 +74,37 @@ pub(crate) struct GlobalState {
     pub(crate) vfs_progress_n_total: usize,
     pub(crate) vfs_progress_n_done: usize,
 
-    /// For both `workspaces` and `workspace_build_data`, the field stores the
-    /// data we actually use, while the `OpQueue` stores the result of the last
-    /// fetch.
+    /// `workspaces` field stores the data we actually use, while the `OpQueue`
+    /// stores the result of the last fetch.
     ///
-    /// If the fetch (partially) fails, we do not update the values.
+    /// If the fetch (partially) fails, we do not update the current value.
+    ///
+    /// The handling of build data is subtle. We fetch workspace in two phases:
+    ///
+    /// *First*, we run `cargo metadata`, which gives us fast results for
+    /// initial analysis.
+    ///
+    /// *Second*, we run `cargo check` which runs build scripts and compiles
+    /// proc macros.
+    ///
+    /// We need both for the precise analysis, but we want rust-analyzer to be
+    /// at least partially available just after the first phase. That's because
+    /// first phase is much faster, and is much less likely to fail.
+    ///
+    /// This creates a complication -- by the time the second phase completes,
+    /// the results of the fist phase could be invalid. That is, while we run
+    /// `cargo check`, the user edits `Cargo.toml`, we notice this, and the new
+    /// `cargo metadata` completes before `cargo check`.
+    ///
+    /// An additional complication is that we want to avoid needless work. When
+    /// the user just adds comments or whitespace to Cargo.toml, we do not want
+    /// to invalidate any salsa caches.
     pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
-    pub(crate) fetch_workspaces_queue: OpQueue<(), Vec<anyhow::Result<ProjectWorkspace>>>,
-    pub(crate) workspace_build_data: Option<BuildDataResult>,
+    pub(crate) fetch_workspaces_queue: OpQueue<Vec<anyhow::Result<ProjectWorkspace>>>,
     pub(crate) fetch_build_data_queue:
-        OpQueue<BuildDataCollector, Option<anyhow::Result<BuildDataResult>>>,
-    pub(crate) prime_caches_queue: OpQueue<(), ()>,
+        OpQueue<(Arc<Vec<ProjectWorkspace>>, Vec<anyhow::Result<WorkspaceBuildScripts>>)>,
+
+    pub(crate) prime_caches_queue: OpQueue<()>,
 
     latest_requests: Arc<RwLock<LatestRequests>>,
 }
@@ -95,7 +115,7 @@ pub(crate) struct GlobalStateSnapshot {
     pub(crate) analysis: Analysis,
     pub(crate) check_fixes: CheckFixes,
     pub(crate) latest_requests: Arc<RwLock<LatestRequests>>,
-    mem_docs: FxHashMap<VfsPath, DocumentData>,
+    mem_docs: MemDocs,
     pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
     vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
     pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
@@ -127,7 +147,7 @@ pub(crate) fn new(sender: Sender<lsp_server::Message>, config: Config) -> Global
             config: Arc::new(config.clone()),
             analysis_host,
             diagnostics: Default::default(),
-            mem_docs: FxHashMap::default(),
+            mem_docs: MemDocs::default(),
             semantic_tokens_cache: Arc::new(Default::default()),
             shutdown_requested: false,
             last_reported_status: None,
@@ -146,7 +166,6 @@ pub(crate) fn new(sender: Sender<lsp_server::Message>, config: Config) -> Global
 
             workspaces: Arc::new(Vec::new()),
             fetch_workspaces_queue: OpQueue::default(),
-            workspace_build_data: None,
             prime_caches_queue: OpQueue::default(),
 
             fetch_build_data_queue: OpQueue::default(),