Skip to main content

GlobalState

Struct GlobalState 

Source
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: DeferredTaskQueue

A 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: bool

HACK: 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: Revision

Implementations§

Source§

impl GlobalState

Source

fn run(self, inbox: Receiver<Message>) -> Result<()>

Source

fn register_did_save_capability( &mut self, additional_patterns: impl Iterator<Item = String>, )

Source

fn next_event( &mut self, inbox: &Receiver<Message>, ) -> Result<Option<Event>, RecvError>

Source

fn handle_event(&mut self, event: Event)

Source

fn prime_caches(&mut self, cause: String)

Source

fn update_diagnostics(&mut self)

Source

fn update_tests(&mut self)

Source

fn update_status_or_notify(&mut self)

Source

fn handle_task( &mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task, )

Source

fn handle_vfs_msg( &mut self, message: Message, last_progress_report: &mut Option<(String, f64)>, )

Source

fn handle_deferred_task(&mut self, task: DeferredTask)

Source

fn handle_discover_msg(&mut self, message: DiscoverProjectMessage)

Source

fn cleanup_discover_handles(&mut self)

Drop any discover command processes that have exited, due to finishing or erroring.

Source

fn handle_cargo_test_msg(&mut self, message: CargoTestMessage)

Source

fn handle_flycheck_msg( &mut self, message: FlycheckMessage, cargo_finished: &mut bool, )

Source

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.

Source

fn on_request(&mut self, req: Request)

Handles a request.

Source

fn on_notification(&mut self, not: Notification)

Handles an incoming notification.

Source§

impl GlobalState

Source

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.

Source

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.

Source

pub(crate) fn update_configuration(&mut self, config: Config)

Source

pub(crate) fn current_status(&self) -> ServerStatusParams

Source

pub(crate) fn fetch_workspaces( &mut self, cause: String, path: Option<AbsPathBuf>, force_crate_graph_reload: bool, )

Source

pub(crate) fn fetch_build_data(&mut self, cause: String)

Source

pub(crate) fn fetch_proc_macros( &mut self, cause: String, change: ChangeWithProcMacros, paths: Vec<ProcMacroPaths>, )

Source

pub(crate) fn switch_workspaces(&mut self, cause: String)

Source

fn recreate_crate_graph(&mut self, cause: String, initial_build: bool)

Source

pub(crate) fn finish_loading_crate_graph(&mut self)

Source

pub(crate) fn fetch_workspace_error(&self) -> Result<(), String>

Source

pub(crate) fn fetch_build_data_error(&self) -> Result<(), String>

Source

fn reload_flycheck(&mut self)

Source§

impl GlobalState

Source

pub(crate) fn new(sender: Sender<Message>, config: Config) -> GlobalState

Source

pub(crate) fn process_changes(&mut self) -> bool

Source

pub(crate) fn snapshot(&self) -> GlobalStateSnapshot

Source

pub(crate) fn send_request<R: Request>( &mut self, params: R::Params, handler: fn(&mut GlobalState, Response), )

Source

pub(crate) fn complete_request(&mut self, response: Response)

Source

pub(crate) fn send_notification<N: Notification>(&self, params: N::Params)

Source

pub(crate) fn register_request( &mut self, request: &Request, request_received: Instant, )

Source

pub(crate) fn respond(&mut self, response: Response)

Source

pub(crate) fn cancel(&mut self, request_id: RequestId)

Source

pub(crate) fn is_completed(&self, request: &Request) -> bool

Source

fn send(&self, message: Message)

Source

pub(crate) fn publish_diagnostics( &mut self, uri: Url, version: Option<i32>, diagnostics: Vec<Diagnostic>, )

Source

pub(crate) fn check_workspaces_msrv(&self) -> impl Iterator<Item = String> + '_

Source

fn enqueue_workspace_fetch( &mut self, path: AbsPathBuf, force_crate_graph_reload: bool, )

Source

pub(crate) fn debounce_workspace_fetch(&mut self)

Source§

impl GlobalState

Source

pub(crate) fn show_message( &mut self, typ: MessageType, message: String, show_open_log_button: bool, )

Source

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.

Source

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!

Source

pub(crate) fn report_progress( &mut self, title: &str, state: Progress, message: Option<String>, fraction: Option<f64>, cancel_token: Option<String>, )

Trait Implementations§

Source§

impl Drop for GlobalState

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T, R> CollectAndApply<T, R> for T

§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

§

type Output = R

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoBox<dyn Any> for T
where T: Any,

§

fn into_box(self) -> Box<dyn Any>

Convert self into the appropriate boxed form.
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Lookup<T> for T

§

fn into_owned(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

§

fn upcast(self, interner: I) -> U

§

impl<I, T> UpcastFrom<I, T> for T

§

fn upcast_from(from: T, _tcx: I) -> T

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,