pub(crate) struct GlobalState {Show 49 fields
sender: Sender<Message>,
req_queue: ReqQueue<(String, Instant), fn(&mut GlobalState, Response)>,
pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
pub(crate) fmt_pool: Handle<TaskPool<Task>, Receiver<Task>>,
pub(crate) cancellation_pool: Pool,
pub(crate) config: Arc<Config>,
pub(crate) config_errors: Option<ConfigErrors>,
pub(crate) analysis_host: AnalysisHost,
pub(crate) diagnostics: DiagnosticCollection,
pub(crate) mem_docs: MemDocs,
pub(crate) source_root_config: SourceRootConfig,
pub(crate) local_roots_parent_map: Arc<FxHashMap<SourceRootId, SourceRootId>>,
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
pub(crate) shutdown_requested: bool,
pub(crate) last_reported_status: ServerStatusParams,
pub(crate) proc_macro_clients: Arc<[Option<Result<ProcMacroClient>>]>,
pub(crate) build_deps_changed: bool,
pub(crate) flycheck: Arc<[FlycheckHandle]>,
pub(crate) flycheck_sender: Sender<FlycheckMessage>,
pub(crate) flycheck_receiver: Receiver<FlycheckMessage>,
pub(crate) last_flycheck_error: Option<String>,
pub(crate) flycheck_formatted_commands: Vec<String>,
pub(crate) test_run_session: Option<Vec<CargoTestHandle>>,
pub(crate) test_run_sender: Sender<CargoTestMessage>,
pub(crate) test_run_receiver: Receiver<CargoTestMessage>,
pub(crate) test_run_remaining_jobs: usize,
pub(crate) discover_handles: Vec<DiscoverHandle>,
pub(crate) discover_sender: Sender<DiscoverProjectMessage>,
pub(crate) discover_receiver: Receiver<DiscoverProjectMessage>,
pub(crate) discover_jobs_active: u32,
pub(crate) fetch_ws_receiver: Option<(Receiver<Instant>, FetchWorkspaceRequest)>,
pub(crate) loader: Handle<Box<dyn Handle>, Receiver<Message>>,
pub(crate) vfs: Arc<RwLock<(Vfs, FxHashMap<FileId, LineEndings>)>>,
pub(crate) vfs_config_version: u32,
pub(crate) vfs_progress_config_version: u32,
pub(crate) vfs_done: bool,
pub(crate) vfs_span: Option<EnteredSpan>,
pub(crate) wants_to_switch: Option<String>,
pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
pub(crate) crate_graph_file_dependencies: FxHashSet<VfsPath>,
pub(crate) detached_files: FxHashSet<ManifestPath>,
pub(crate) fetch_workspaces_queue: OpQueue<FetchWorkspaceRequest, FetchWorkspaceResponse>,
pub(crate) fetch_build_data_queue: OpQueue<(), FetchBuildDataResponse>,
pub(crate) fetch_proc_macros_queue: OpQueue<(ChangeWithProcMacros, Vec<ProcMacroPaths>), bool>,
pub(crate) prime_caches_queue: OpQueue,
pub(crate) deferred_task_queue: DeferredTaskQueue,
pub(crate) incomplete_crate_graph: bool,
pub(crate) minicore: MiniCoreRustAnalyzerInternalOnly,
pub(crate) last_gc_revision: Revision,
}Expand description
GlobalState is the primary mutable state of the language server
The most interesting components are vfs, which stores a consistent
snapshot of the file systems, and analysis_host, which stores our
incremental salsa database.
Note that this struct has more than one impl in various modules!
Fields§
§sender: Sender<Message>§req_queue: ReqQueue<(String, Instant), fn(&mut GlobalState, Response)>§task_pool: Handle<TaskPool<Task>, Receiver<Task>>§fmt_pool: Handle<TaskPool<Task>, Receiver<Task>>§cancellation_pool: Pool§config: Arc<Config>§config_errors: Option<ConfigErrors>§analysis_host: AnalysisHost§diagnostics: DiagnosticCollection§mem_docs: MemDocs§source_root_config: SourceRootConfig§local_roots_parent_map: Arc<FxHashMap<SourceRootId, SourceRootId>>A mapping that maps a local source root’s SourceRootId to it parent’s SourceRootId, if it has one.
semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>§shutdown_requested: bool§last_reported_status: ServerStatusParams§proc_macro_clients: Arc<[Option<Result<ProcMacroClient>>]>§build_deps_changed: bool§flycheck: Arc<[FlycheckHandle]>§flycheck_sender: Sender<FlycheckMessage>§flycheck_receiver: Receiver<FlycheckMessage>§last_flycheck_error: Option<String>§flycheck_formatted_commands: Vec<String>§test_run_session: Option<Vec<CargoTestHandle>>§test_run_sender: Sender<CargoTestMessage>§test_run_receiver: Receiver<CargoTestMessage>§test_run_remaining_jobs: usize§discover_handles: Vec<DiscoverHandle>§discover_sender: Sender<DiscoverProjectMessage>§discover_receiver: Receiver<DiscoverProjectMessage>§discover_jobs_active: u32§fetch_ws_receiver: Option<(Receiver<Instant>, FetchWorkspaceRequest)>§loader: Handle<Box<dyn Handle>, Receiver<Message>>§vfs: Arc<RwLock<(Vfs, FxHashMap<FileId, LineEndings>)>>§vfs_config_version: u32§vfs_progress_config_version: u32§vfs_done: bool§vfs_span: Option<EnteredSpan>§wants_to_switch: Option<String>§workspaces: Arc<Vec<ProjectWorkspace>>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 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 first 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.
crate_graph_file_dependencies: FxHashSet<VfsPath>§detached_files: FxHashSet<ManifestPath>§fetch_workspaces_queue: OpQueue<FetchWorkspaceRequest, FetchWorkspaceResponse>§fetch_build_data_queue: OpQueue<(), FetchBuildDataResponse>§fetch_proc_macros_queue: OpQueue<(ChangeWithProcMacros, Vec<ProcMacroPaths>), bool>§prime_caches_queue: OpQueue§deferred_task_queue: DeferredTaskQueueA deferred task queue.
This queue is used for doing database-dependent work inside of sync handlers, as accessing the database may block latency-sensitive interactions and should be moved away from the main thread.
For certain features, such as GlobalState::handle_discover_msg,
this queue should run only after GlobalState::process_changes has
been called.
incomplete_crate_graph: boolHACK: Workaround for https://github.com/rust-lang/rust-analyzer/issues/19709 This is marked true if we failed to load a crate root file at crate graph creation, which will usually end up causing a bunch of incorrect diagnostics on startup.
minicore: MiniCoreRustAnalyzerInternalOnly§last_gc_revision: RevisionImplementations§
Source§impl GlobalState
impl GlobalState
fn run(self, inbox: Receiver<Message>) -> Result<()>
fn register_did_save_capability( &mut self, additional_patterns: impl Iterator<Item = String>, )
fn next_event( &mut self, inbox: &Receiver<Message>, ) -> Result<Option<Event>, RecvError>
fn handle_event(&mut self, event: Event)
fn prime_caches(&mut self, cause: String)
fn update_diagnostics(&mut self)
fn update_tests(&mut self)
fn update_status_or_notify(&mut self)
fn handle_task( &mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task, )
fn handle_vfs_msg( &mut self, message: Message, last_progress_report: &mut Option<(String, f64)>, )
fn handle_deferred_task(&mut self, task: DeferredTask)
fn handle_discover_msg(&mut self, message: DiscoverProjectMessage)
Sourcefn cleanup_discover_handles(&mut self)
fn cleanup_discover_handles(&mut self)
Drop any discover command processes that have exited, due to finishing or erroring.
fn handle_cargo_test_msg(&mut self, message: CargoTestMessage)
fn handle_flycheck_msg( &mut self, message: FlycheckMessage, cargo_finished: &mut bool, )
Sourcefn on_new_request(&mut self, request_received: Instant, req: Request)
fn on_new_request(&mut self, request_received: Instant, req: Request)
Registers and handles a request. This should only be called once per incoming request.
Sourcefn on_request(&mut self, req: Request)
fn on_request(&mut self, req: Request)
Handles a request.
Sourcefn on_notification(&mut self, not: Notification)
fn on_notification(&mut self, not: Notification)
Handles an incoming notification.
Source§impl GlobalState
impl GlobalState
Sourcepub(crate) fn is_quiescent(&self) -> bool
pub(crate) fn is_quiescent(&self) -> bool
Is the server quiescent?
This indicates that we’ve fully loaded the projects and are ready to do semantic work.
Sourcefn is_fully_ready(&self) -> bool
fn is_fully_ready(&self) -> bool
Is the server ready to respond to analysis dependent LSP requests?
Unlike is_quiescent, this returns false when we’re indexing
the project, because we’re holding the salsa lock and cannot
respond to LSP requests that depend on salsa data.
pub(crate) fn update_configuration(&mut self, config: Config)
pub(crate) fn current_status(&self) -> ServerStatusParams
pub(crate) fn fetch_workspaces( &mut self, cause: String, path: Option<AbsPathBuf>, force_crate_graph_reload: bool, )
pub(crate) fn fetch_build_data(&mut self, cause: String)
pub(crate) fn fetch_proc_macros( &mut self, cause: String, change: ChangeWithProcMacros, paths: Vec<ProcMacroPaths>, )
pub(crate) fn switch_workspaces(&mut self, cause: String)
fn recreate_crate_graph(&mut self, cause: String, initial_build: bool)
pub(crate) fn finish_loading_crate_graph(&mut self)
pub(crate) fn fetch_workspace_error(&self) -> Result<(), String>
pub(crate) fn fetch_build_data_error(&self) -> Result<(), String>
fn reload_flycheck(&mut self)
Source§impl GlobalState
impl GlobalState
pub(crate) fn new(sender: Sender<Message>, config: Config) -> GlobalState
pub(crate) fn process_changes(&mut self) -> bool
pub(crate) fn snapshot(&self) -> GlobalStateSnapshot
pub(crate) fn send_request<R: Request>( &mut self, params: R::Params, handler: fn(&mut GlobalState, Response), )
pub(crate) fn complete_request(&mut self, response: Response)
pub(crate) fn send_notification<N: Notification>(&self, params: N::Params)
pub(crate) fn register_request( &mut self, request: &Request, request_received: Instant, )
pub(crate) fn respond(&mut self, response: Response)
pub(crate) fn cancel(&mut self, request_id: RequestId)
pub(crate) fn is_completed(&self, request: &Request) -> bool
fn send(&self, message: Message)
pub(crate) fn publish_diagnostics( &mut self, uri: Url, version: Option<i32>, diagnostics: Vec<Diagnostic>, )
pub(crate) fn check_workspaces_msrv(&self) -> impl Iterator<Item = String> + '_
fn enqueue_workspace_fetch( &mut self, path: AbsPathBuf, force_crate_graph_reload: bool, )
pub(crate) fn debounce_workspace_fetch(&mut self)
Source§impl GlobalState
impl GlobalState
pub(crate) fn show_message( &mut self, typ: MessageType, message: String, show_open_log_button: bool, )
Sourcepub(crate) fn show_and_log_error(
&mut self,
message: String,
additional_info: Option<String>,
)
pub(crate) fn show_and_log_error( &mut self, message: String, additional_info: Option<String>, )
If additional_info is Some, appends a note to the notification telling to check the logs.
This will always log message + additional_info to the server’s error log.
Sourcepub(crate) fn poke_rust_analyzer_developer(&mut self, message: String)
pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String)
rust-analyzer is resilient – if it fails, this doesn’t usually affect the user experience. Part of that is that we deliberately hide panics from the user.
We do however want to pester rust-analyzer developers with panics and other “you really gotta fix that” messages. The current strategy is to be noisy for “from source” builds or when profiling is enabled.
It’s unclear if making from source cargo xtask install builds more
panicky is a good idea, let’s see if we can keep our awesome bleeding
edge users from being upset!
pub(crate) fn report_progress( &mut self, title: &str, state: Progress, message: Option<String>, fraction: Option<f64>, cancel_token: Option<String>, )
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for GlobalState
impl !RefUnwindSafe for GlobalState
impl !Send for GlobalState
impl !Sync for GlobalState
impl Unpin for GlobalState
impl UnsafeUnpin for GlobalState
impl !UnwindSafe for GlobalState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more