Skip to content

Commit e2da967

Browse files
committed
fix: Fix completions disappearing when typing two keys in quick succession
1 parent 1234d86 commit e2da967

File tree

7 files changed

+83
-74
lines changed

7 files changed

+83
-74
lines changed

crates/rust-analyzer/src/bin/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn run_server() -> Result<()> {
157157
let (initialize_id, initialize_params) = connection.initialize_start()?;
158158
tracing::info!("InitializeParams: {}", initialize_params);
159159
let initialize_params =
160-
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
160+
from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?;
161161

162162
let root_path = match initialize_params
163163
.root_uri

crates/rust-analyzer/src/dispatch.rs

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! See [RequestDispatcher].
22
use std::{fmt, panic, thread};
33

4+
use ide::Cancelled;
45
use lsp_server::ExtractError;
56
use serde::{de::DeserializeOwned, Serialize};
67

78
use crate::{
89
global_state::{GlobalState, GlobalStateSnapshot},
9-
lsp_utils::is_cancelled,
1010
main_loop::Task,
1111
LspError, Result,
1212
};
@@ -37,49 +37,55 @@ impl<'a> RequestDispatcher<'a> {
3737
pub(crate) fn on_sync_mut<R>(
3838
&mut self,
3939
f: fn(&mut GlobalState, R::Params) -> Result<R::Result>,
40-
) -> Result<&mut Self>
40+
) -> &mut Self
4141
where
4242
R: lsp_types::request::Request,
4343
R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug,
4444
R::Result: Serialize,
4545
{
46-
let (id, params, panic_context) = match self.parse::<R>() {
46+
let (req, params, panic_context) = match self.parse::<R>() {
4747
Some(it) => it,
48-
None => return Ok(self),
48+
None => return self,
49+
};
50+
let result = {
51+
let _pctx = stdx::panic_context::enter(panic_context);
52+
f(self.global_state, params)
53+
};
54+
match result_to_response::<R>(req.id.clone(), result) {
55+
Ok(response) => self.global_state.respond(response),
56+
Err(_) => self.global_state.task_pool.handle.send_retry(req),
4957
};
50-
let _pctx = stdx::panic_context::enter(panic_context);
51-
52-
let result = f(self.global_state, params);
53-
let response = result_to_response::<R>(id, result);
5458

55-
self.global_state.respond(response);
56-
Ok(self)
59+
self
5760
}
5861

5962
/// Dispatches the request onto the current thread.
6063
pub(crate) fn on_sync<R>(
6164
&mut self,
6265
f: fn(GlobalStateSnapshot, R::Params) -> Result<R::Result>,
63-
) -> Result<&mut Self>
66+
) -> &mut Self
6467
where
65-
R: lsp_types::request::Request + 'static,
68+
R: lsp_types::request::Request,
6669
R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug,
6770
R::Result: Serialize,
6871
{
69-
let (id, params, panic_context) = match self.parse::<R>() {
72+
let (req, params, panic_context) = match self.parse::<R>() {
7073
Some(it) => it,
71-
None => return Ok(self),
74+
None => return self,
7275
};
7376
let global_state_snapshot = self.global_state.snapshot();
7477

7578
let result = panic::catch_unwind(move || {
7679
let _pctx = stdx::panic_context::enter(panic_context);
7780
f(global_state_snapshot, params)
7881
});
79-
let response = thread_result_to_response::<R>(id, result);
8082

81-
self.global_state.respond(response);
82-
Ok(self)
83+
match thread_result_to_response::<R>(req.id.clone(), result) {
84+
Ok(response) => self.global_state.respond(response),
85+
Err(_) => self.global_state.task_pool.handle.send_retry(req),
86+
};
87+
88+
self
8389
}
8490

8591
/// Dispatches the request onto thread pool
@@ -92,7 +98,7 @@ impl<'a> RequestDispatcher<'a> {
9298
R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug,
9399
R::Result: Serialize,
94100
{
95-
let (id, params, panic_context) = match self.parse::<R>() {
101+
let (req, params, panic_context) = match self.parse::<R>() {
96102
Some(it) => it,
97103
None => return self,
98104
};
@@ -104,8 +110,10 @@ impl<'a> RequestDispatcher<'a> {
104110
let _pctx = stdx::panic_context::enter(panic_context);
105111
f(world, params)
106112
});
107-
let response = thread_result_to_response::<R>(id, result);
108-
Task::Response(response)
113+
match thread_result_to_response::<R>(req.id.clone(), result) {
114+
Ok(response) => Task::Response(response),
115+
Err(_) => Task::Retry(req),
116+
}
109117
}
110118
});
111119

@@ -124,7 +132,7 @@ impl<'a> RequestDispatcher<'a> {
124132
}
125133
}
126134

127-
fn parse<R>(&mut self) -> Option<(lsp_server::RequestId, R::Params, String)>
135+
fn parse<R>(&mut self) -> Option<(lsp_server::Request, R::Params, String)>
128136
where
129137
R: lsp_types::request::Request,
130138
R::Params: DeserializeOwned + fmt::Debug,
@@ -134,12 +142,12 @@ impl<'a> RequestDispatcher<'a> {
134142
_ => return None,
135143
};
136144

137-
let res = crate::from_json(R::METHOD, req.params);
145+
let res = crate::from_json(R::METHOD, &req.params);
138146
match res {
139147
Ok(params) => {
140148
let panic_context =
141149
format!("\nversion: {}\nrequest: {} {:#?}", env!("REV"), R::METHOD, params);
142-
Some((req.id, params, panic_context))
150+
Some((req, params, panic_context))
143151
}
144152
Err(err) => {
145153
let response = lsp_server::Response::new_err(
@@ -157,7 +165,7 @@ impl<'a> RequestDispatcher<'a> {
157165
fn thread_result_to_response<R>(
158166
id: lsp_server::RequestId,
159167
result: thread::Result<Result<R::Result>>,
160-
) -> lsp_server::Response
168+
) -> Result<lsp_server::Response, Cancelled>
161169
where
162170
R: lsp_types::request::Request,
163171
R::Params: DeserializeOwned,
@@ -166,53 +174,50 @@ where
166174
match result {
167175
Ok(result) => result_to_response::<R>(id, result),
168176
Err(panic) => {
169-
let mut message = "request handler panicked".to_string();
170-
171177
let panic_message = panic
172178
.downcast_ref::<String>()
173179
.map(String::as_str)
174180
.or_else(|| panic.downcast_ref::<&str>().copied());
175181

182+
let mut message = "request handler panicked".to_string();
176183
if let Some(panic_message) = panic_message {
177184
message.push_str(": ");
178185
message.push_str(panic_message)
179186
};
180187

181-
lsp_server::Response::new_err(id, lsp_server::ErrorCode::InternalError as i32, message)
188+
Ok(lsp_server::Response::new_err(
189+
id,
190+
lsp_server::ErrorCode::InternalError as i32,
191+
message,
192+
))
182193
}
183194
}
184195
}
185196

186197
fn result_to_response<R>(
187198
id: lsp_server::RequestId,
188199
result: Result<R::Result>,
189-
) -> lsp_server::Response
200+
) -> Result<lsp_server::Response, Cancelled>
190201
where
191202
R: lsp_types::request::Request,
192203
R::Params: DeserializeOwned,
193204
R::Result: Serialize,
194205
{
195-
match result {
206+
let res = match result {
196207
Ok(resp) => lsp_server::Response::new_ok(id, &resp),
197208
Err(e) => match e.downcast::<LspError>() {
198209
Ok(lsp_error) => lsp_server::Response::new_err(id, lsp_error.code, lsp_error.message),
199-
Err(e) => {
200-
if is_cancelled(&*e) {
201-
lsp_server::Response::new_err(
202-
id,
203-
lsp_server::ErrorCode::ContentModified as i32,
204-
"content modified".to_string(),
205-
)
206-
} else {
207-
lsp_server::Response::new_err(
208-
id,
209-
lsp_server::ErrorCode::InternalError as i32,
210-
e.to_string(),
211-
)
212-
}
213-
}
210+
Err(e) => match e.downcast::<Cancelled>() {
211+
Ok(cancelled) => return Err(*cancelled),
212+
Err(e) => lsp_server::Response::new_err(
213+
id,
214+
lsp_server::ErrorCode::InternalError as i32,
215+
e.to_string(),
216+
),
217+
},
214218
},
215-
}
219+
};
220+
Ok(res)
216221
}
217222

218223
pub(crate) struct NotificationDispatcher<'a> {

crates/rust-analyzer/src/from_proto.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub(crate) fn annotation(
9191
) -> Result<Annotation> {
9292
let data =
9393
code_lens.data.ok_or_else(|| invalid_params_error("code lens without data".to_string()))?;
94-
let resolve = from_json::<lsp_ext::CodeLensResolveData>("CodeLensResolveData", data)?;
94+
let resolve = from_json::<lsp_ext::CodeLensResolveData>("CodeLensResolveData", &data)?;
9595

9696
match resolve {
9797
lsp_ext::CodeLensResolveData::Impls(params) => {

crates/rust-analyzer/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub use crate::{caps::server_capabilities, main_loop::main_loop};
4949
pub type Error = Box<dyn std::error::Error + Send + Sync>;
5050
pub type Result<T, E = Error> = std::result::Result<T, E>;
5151

52-
pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> {
52+
pub fn from_json<T: DeserializeOwned>(what: &'static str, json: &serde_json::Value) -> Result<T> {
5353
let res = serde_json::from_value(json.clone())
5454
.map_err(|e| format!("Failed to deserialize {}: {}; {}", what, e, json))?;
5555
Ok(res)

crates/rust-analyzer/src/lsp_utils.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Utilities for LSP-related boilerplate code.
2-
use std::{error::Error, ops::Range, sync::Arc};
2+
use std::{ops::Range, sync::Arc};
33

4-
use ide_db::base_db::Cancelled;
54
use lsp_server::Notification;
65

76
use crate::{
@@ -15,10 +14,6 @@ pub(crate) fn invalid_params_error(message: String) -> LspError {
1514
LspError { code: lsp_server::ErrorCode::InvalidParams as i32, message }
1615
}
1716

18-
pub(crate) fn is_cancelled(e: &(dyn Error + 'static)) -> bool {
19-
e.downcast_ref::<Cancelled>().is_some()
20-
}
21-
2217
pub(crate) fn notification_is<N: lsp_types::notification::Notification>(
2318
notification: &Notification,
2419
) -> bool {

crates/rust-analyzer/src/main_loop.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88

99
use always_assert::always;
1010
use crossbeam_channel::{select, Receiver};
11-
use ide_db::base_db::{SourceDatabaseExt, VfsPath};
11+
use ide_db::base_db::{Cancelled, SourceDatabaseExt, VfsPath};
1212
use lsp_server::{Connection, Notification, Request};
1313
use lsp_types::notification::Notification as _;
1414
use vfs::{ChangeKind, FileId};
@@ -19,7 +19,7 @@ use crate::{
1919
from_proto,
2020
global_state::{file_id_to_url, url_to_file_id, GlobalState},
2121
handlers, lsp_ext,
22-
lsp_utils::{apply_document_changes, is_cancelled, notification_is, Progress},
22+
lsp_utils::{apply_document_changes, notification_is, Progress},
2323
mem_docs::DocumentData,
2424
reload::{self, BuildDataProgress, ProjectWorkspaceProgress},
2525
Result,
@@ -60,6 +60,7 @@ enum Event {
6060
#[derive(Debug)]
6161
pub(crate) enum Task {
6262
Response(lsp_server::Response),
63+
Retry(lsp_server::Request),
6364
Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>),
6465
PrimeCaches(PrimeCachesProgress),
6566
FetchWorkspace(ProjectWorkspaceProgress),
@@ -172,13 +173,13 @@ impl GlobalState {
172173
msg.ok().map(Event::Lsp),
173174

174175
recv(self.task_pool.receiver) -> task =>
175-
Some(Event::Task(task.unwrap())),
176+
task.ok().map(Event::Task),
176177

177178
recv(self.loader.receiver) -> task =>
178-
Some(Event::Vfs(task.unwrap())),
179+
task.ok().map(Event::Vfs),
179180

180181
recv(self.flycheck_receiver) -> task =>
181-
Some(Event::Flycheck(task.unwrap())),
182+
task.ok().map(Event::Flycheck),
182183
}
183184
}
184185

@@ -196,7 +197,7 @@ impl GlobalState {
196197
let was_quiescent = self.is_quiescent();
197198
match event {
198199
Event::Lsp(msg) => match msg {
199-
lsp_server::Message::Request(req) => self.on_request(loop_start, req)?,
200+
lsp_server::Message::Request(req) => self.on_request(loop_start, req),
200201
lsp_server::Message::Notification(not) => {
201202
self.on_notification(not)?;
202203
}
@@ -208,6 +209,7 @@ impl GlobalState {
208209
loop {
209210
match task {
210211
Task::Response(response) => self.respond(response),
212+
Task::Retry(req) => self.on_request(loop_start, req),
211213
Task::Diagnostics(diagnostics_per_file) => {
212214
for (file_id, diagnostics) in diagnostics_per_file {
213215
self.diagnostics.set_native_diagnostics(file_id, diagnostics)
@@ -553,7 +555,7 @@ impl GlobalState {
553555
Ok(())
554556
}
555557

556-
fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
558+
fn on_request(&mut self, request_received: Instant, req: Request) {
557559
self.register_request(&req, request_received);
558560

559561
if self.shutdown_requested {
@@ -562,8 +564,7 @@ impl GlobalState {
562564
lsp_server::ErrorCode::InvalidRequest as i32,
563565
"Shutdown already requested.".to_owned(),
564566
));
565-
566-
return Ok(());
567+
return;
567568
}
568569

569570
// Avoid flashing a bunch of unresolved references during initial load.
@@ -573,21 +574,21 @@ impl GlobalState {
573574
lsp_server::ErrorCode::ContentModified as i32,
574575
"waiting for cargo metadata or cargo check".to_owned(),
575576
));
576-
return Ok(());
577+
return;
577578
}
578579

579580
RequestDispatcher { req: Some(req), global_state: self }
580581
.on_sync_mut::<lsp_types::request::Shutdown>(|s, ()| {
581582
s.shutdown_requested = true;
582583
Ok(())
583-
})?
584-
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)?
585-
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)?
586-
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)?
587-
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)?
588-
.on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)?
589-
.on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)?
590-
.on_sync::<lsp_ext::MatchingBrace>(handlers::handle_matching_brace)?
584+
})
585+
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
586+
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
587+
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
588+
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
589+
.on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
590+
.on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
591+
.on_sync::<lsp_ext::MatchingBrace>(handlers::handle_matching_brace)
591592
.on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)
592593
.on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)
593594
.on::<lsp_ext::ViewHir>(handlers::handle_view_hir)
@@ -644,8 +645,8 @@ impl GlobalState {
644645
.on::<lsp_types::request::WillRenameFiles>(handlers::handle_will_rename_files)
645646
.on::<lsp_ext::Ssr>(handlers::handle_ssr)
646647
.finish();
647-
Ok(())
648648
}
649+
649650
fn on_notification(&mut self, not: Notification) -> Result<()> {
650651
NotificationDispatcher { not: Some(not), global_state: self }
651652
.on::<lsp_types::notification::Cancel>(|this, params| {
@@ -792,7 +793,7 @@ impl GlobalState {
792793
.filter_map(|file_id| {
793794
handlers::publish_diagnostics(&snapshot, file_id)
794795
.map_err(|err| {
795-
if !is_cancelled(&*err) {
796+
if err.is::<Cancelled>() {
796797
tracing::error!("failed to compute diagnostics: {:?}", err);
797798
}
798799
})

0 commit comments

Comments
 (0)