Skip to content

Commit 5e753ff

Browse files
committed
Auto merge of rust-lang#17850 - Veykril:rust-analyzer-crate, r=Veykril
internal: Reply to requests with defaults when vfs is still loading There is no reason for us to hit the database with queries when we certainly haven't reached a stable state yet. Instead we just reply with default request results until we are in a state where we can do meaningful work. This should save us from wasting resources while starting up at worst, and at best save us from creating query and interning entries that are non-meaningful which ultimately just end up wasting memory.
2 parents 563dc1c + 234d383 commit 5e753ff

File tree

5 files changed

+71
-27
lines changed

5 files changed

+71
-27
lines changed

src/tools/rust-analyzer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exclude = ["crates/proc-macro-srv/proc-macro-test/imp"]
44
resolver = "2"
55

66
[workspace.package]
7-
rust-version = "1.78"
7+
rust-version = "1.80"
88
edition = "2021"
99
license = "MIT OR Apache-2.0"
1010
authors = ["rust-analyzer team"]

src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,45 @@ impl RequestDispatcher<'_> {
9797
self
9898
}
9999

100-
/// Dispatches a non-latency-sensitive request onto the thread pool.
100+
/// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not
101+
/// ready this will return a default constructed [`R::Result`].
101102
pub(crate) fn on<const ALLOW_RETRYING: bool, R>(
102103
&mut self,
103104
f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>,
104105
) -> &mut Self
105106
where
106-
R: lsp_types::request::Request + 'static,
107-
R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
108-
R::Result: Serialize,
107+
R: lsp_types::request::Request<
108+
Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
109+
Result: Serialize + Default,
110+
> + 'static,
111+
{
112+
if !self.global_state.vfs_done {
113+
if let Some(lsp_server::Request { id, .. }) =
114+
self.req.take_if(|it| it.method == R::METHOD)
115+
{
116+
self.global_state.respond(lsp_server::Response::new_ok(id, R::Result::default()));
117+
}
118+
return self;
119+
}
120+
self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(ThreadIntent::Worker, f)
121+
}
122+
123+
/// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not
124+
/// ready this will return the parameter as is.
125+
pub(crate) fn on_identity<const ALLOW_RETRYING: bool, R, Params>(
126+
&mut self,
127+
f: fn(GlobalStateSnapshot, Params) -> anyhow::Result<R::Result>,
128+
) -> &mut Self
129+
where
130+
R: lsp_types::request::Request<Params = Params, Result = Params> + 'static,
131+
Params: Serialize + DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
109132
{
133+
if !self.global_state.vfs_done {
134+
if let Some((request, params, _)) = self.parse::<R>() {
135+
self.global_state.respond(lsp_server::Response::new_ok(request.id, &params))
136+
}
137+
return self;
138+
}
110139
self.on_with_thread_intent::<true, ALLOW_RETRYING, R>(ThreadIntent::Worker, f)
111140
}
112141

@@ -198,11 +227,7 @@ impl RequestDispatcher<'_> {
198227
R: lsp_types::request::Request,
199228
R::Params: DeserializeOwned + fmt::Debug,
200229
{
201-
let req = match &self.req {
202-
Some(req) if req.method == R::METHOD => self.req.take()?,
203-
_ => return None,
204-
};
205-
230+
let req = self.req.take_if(|it| it.method == R::METHOD)?;
206231
let res = crate::from_json(R::METHOD, &req.params);
207232
match res {
208233
Ok(params) => {

src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl Request for FetchDependencyList {
6161
#[serde(rename_all = "camelCase")]
6262
pub struct FetchDependencyListParams {}
6363

64-
#[derive(Deserialize, Serialize, Debug)]
64+
#[derive(Deserialize, Serialize, Debug, Default)]
6565
#[serde(rename_all = "camelCase")]
6666
pub struct FetchDependencyListResult {
6767
pub crates: Vec<CrateInfoResult>,
@@ -194,7 +194,7 @@ pub struct TestItem {
194194
pub runnable: Option<Runnable>,
195195
}
196196

197-
#[derive(Deserialize, Serialize, Debug)]
197+
#[derive(Deserialize, Serialize, Debug, Default)]
198198
#[serde(rename_all = "camelCase")]
199199
pub struct DiscoverTestResults {
200200
pub tests: Vec<TestItem>,
@@ -690,6 +690,12 @@ pub enum ExternalDocsResponse {
690690
WithLocal(ExternalDocsPair),
691691
}
692692

693+
impl Default for ExternalDocsResponse {
694+
fn default() -> Self {
695+
ExternalDocsResponse::Simple(None)
696+
}
697+
}
698+
693699
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
694700
#[serde(rename_all = "camelCase")]
695701
pub struct ExternalDocsPair {

src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,10 @@ impl GlobalState {
173173
}
174174

175175
if self.config.discover_workspace_config().is_none() {
176-
let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
177-
self.fetch_workspaces_queue.request_op("startup".to_owned(), req);
176+
self.fetch_workspaces_queue.request_op(
177+
"startup".to_owned(),
178+
FetchWorkspaceRequest { path: None, force_crate_graph_reload: false },
179+
);
178180
if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
179181
self.fetch_workspaces_queue.should_start_op()
180182
{
@@ -545,6 +547,10 @@ impl GlobalState {
545547
let snapshot = self.snapshot();
546548
self.task_pool.handle.spawn_with_sender(ThreadIntent::LatencySensitive, {
547549
let subscriptions = subscriptions.clone();
550+
// Do not fetch semantic diagnostics (and populate query results) if we haven't even
551+
// loaded the initial workspace yet.
552+
let fetch_semantic =
553+
self.vfs_done && self.fetch_workspaces_queue.last_op_result().is_some();
548554
move |sender| {
549555
let diags = fetch_native_diagnostics(
550556
&snapshot,
@@ -556,22 +562,29 @@ impl GlobalState {
556562
.send(Task::Diagnostics(DiagnosticsTaskKind::Syntax(generation, diags)))
557563
.unwrap();
558564

559-
let diags = fetch_native_diagnostics(
560-
&snapshot,
561-
subscriptions,
562-
slice,
563-
NativeDiagnosticsFetchKind::Semantic,
564-
);
565-
sender
566-
.send(Task::Diagnostics(DiagnosticsTaskKind::Semantic(generation, diags)))
567-
.unwrap();
565+
if fetch_semantic {
566+
let diags = fetch_native_diagnostics(
567+
&snapshot,
568+
subscriptions,
569+
slice,
570+
NativeDiagnosticsFetchKind::Semantic,
571+
);
572+
sender
573+
.send(Task::Diagnostics(DiagnosticsTaskKind::Semantic(
574+
generation, diags,
575+
)))
576+
.unwrap();
577+
}
568578
}
569579
});
570580
start = end;
571581
}
572582
}
573583

574584
fn update_tests(&mut self) {
585+
if !self.vfs_done {
586+
return;
587+
}
575588
let db = self.analysis_host.raw_database();
576589
let subscriptions = self
577590
.mem_docs
@@ -1052,9 +1065,9 @@ impl GlobalState {
10521065
.on::<NO_RETRY, lsp_request::GotoImplementation>(handlers::handle_goto_implementation)
10531066
.on::<NO_RETRY, lsp_request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
10541067
.on::<NO_RETRY, lsp_request::InlayHintRequest>(handlers::handle_inlay_hints)
1055-
.on::<NO_RETRY, lsp_request::InlayHintResolveRequest>(handlers::handle_inlay_hints_resolve)
1068+
.on_identity::<NO_RETRY, lsp_request::InlayHintResolveRequest, _>(handlers::handle_inlay_hints_resolve)
10561069
.on::<NO_RETRY, lsp_request::CodeLensRequest>(handlers::handle_code_lens)
1057-
.on::<NO_RETRY, lsp_request::CodeLensResolve>(handlers::handle_code_lens_resolve)
1070+
.on_identity::<NO_RETRY, lsp_request::CodeLensResolve, _>(handlers::handle_code_lens_resolve)
10581071
.on::<NO_RETRY, lsp_request::PrepareRenameRequest>(handlers::handle_prepare_rename)
10591072
.on::<NO_RETRY, lsp_request::Rename>(handlers::handle_rename)
10601073
.on::<NO_RETRY, lsp_request::References>(handlers::handle_references)
@@ -1081,7 +1094,7 @@ impl GlobalState {
10811094
.on::<NO_RETRY, lsp_ext::Runnables>(handlers::handle_runnables)
10821095
.on::<NO_RETRY, lsp_ext::RelatedTests>(handlers::handle_related_tests)
10831096
.on::<NO_RETRY, lsp_ext::CodeActionRequest>(handlers::handle_code_action)
1084-
.on::<RETRY, lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
1097+
.on_identity::<RETRY, lsp_ext::CodeActionResolveRequest, _>(handlers::handle_code_action_resolve)
10851098
.on::<NO_RETRY, lsp_ext::HoverRequest>(handlers::handle_hover)
10861099
.on::<NO_RETRY, lsp_ext::ExternalDocs>(handlers::handle_open_docs)
10871100
.on::<NO_RETRY, lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)

src/tools/rust-analyzer/docs/dev/lsp-extensions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
lsp/ext.rs hash: e92e1f12229b0071
2+
lsp/ext.rs hash: 3429c08745984b3d
33
44
If you need to change the above hash to make the test pass, please check if you
55
need to adjust this doc as well and ping this issue:

0 commit comments

Comments
 (0)