diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 0e592ac1bea..658a50d1507 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -73,6 +73,7 @@ pub(crate) struct GlobalState { pub(crate) mem_docs: FxHashMap, pub(crate) semantic_tokens_cache: Arc>>, pub(crate) vfs: Arc)>>, + pub(crate) shutdown_requested: bool, pub(crate) status: Status, pub(crate) source_root_config: SourceRootConfig, pub(crate) proc_macro_client: ProcMacroClient, @@ -124,6 +125,7 @@ impl GlobalState { mem_docs: FxHashMap::default(), semantic_tokens_cache: Arc::new(Default::default()), vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))), + shutdown_requested: false, status: Status::default(), source_root_config: SourceRootConfig::default(), proc_macro_client: ProcMacroClient::dummy(), diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 0ac6434dd79..e6cf46df23e 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -337,6 +337,16 @@ impl GlobalState { fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> { self.register_request(&req, request_received); + if self.shutdown_requested { + self.respond(Response::new_err( + req.id, + lsp_server::ErrorCode::InvalidRequest as i32, + "Shutdown already requested.".to_owned(), + )); + + return Ok(()); + } + if self.status == Status::Loading && req.method != "shutdown" { self.respond(lsp_server::Response::new_err( req.id, @@ -351,7 +361,10 @@ impl GlobalState { .on_sync::(|s, ()| Ok(s.fetch_workspaces()))? .on_sync::(|s, p| handlers::handle_join_lines(s.snapshot(), p))? .on_sync::(|s, p| handlers::handle_on_enter(s.snapshot(), p))? - .on_sync::(|_, ()| Ok(()))? + .on_sync::(|s, ()| { + s.shutdown_requested = true; + Ok(()) + })? .on_sync::(|s, p| { handlers::handle_selection_range(s.snapshot(), p) })?