Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/rust-analyzer/src/dispatch.rs14
-rw-r--r--crates/rust-analyzer/src/handlers/notification.rs14
-rw-r--r--crates/rust-analyzer/src/main_loop.rs140
-rw-r--r--crates/rust-analyzer/src/reload.rs116
-rw-r--r--crates/rust-analyzer/src/task_pool.rs28
5 files changed, 174 insertions, 138 deletions
diff --git a/crates/rust-analyzer/src/dispatch.rs b/crates/rust-analyzer/src/dispatch.rs
index ebe77b8dfe..3527d92a4e 100644
--- a/crates/rust-analyzer/src/dispatch.rs
+++ b/crates/rust-analyzer/src/dispatch.rs
@@ -104,13 +104,10 @@ impl<'a> RequestDispatcher<'a> {
None => return self,
};
- self.global_state.task_pool.handle.spawn(ThreadIntent::Worker, {
+ self.global_state.task_pool.handle.spawn(ThreadIntent::Worker, panic_context, {
let world = self.global_state.snapshot();
move || {
- let result = panic::catch_unwind(move || {
- let _pctx = stdx::panic_context::enter(panic_context);
- f(world, params)
- });
+ let result = panic::catch_unwind(move || f(world, params));
match thread_result_to_response::<R>(req.id.clone(), result) {
Ok(response) => Task::Response(response),
Err(_) => Task::Response(lsp_server::Response::new_err(
@@ -178,13 +175,10 @@ impl<'a> RequestDispatcher<'a> {
None => return self,
};
- self.global_state.task_pool.handle.spawn(intent, {
+ self.global_state.task_pool.handle.spawn(intent, panic_context, {
let world = self.global_state.snapshot();
move || {
- let result = panic::catch_unwind(move || {
- let _pctx = stdx::panic_context::enter(panic_context);
- f(world, params)
- });
+ let result = panic::catch_unwind(move || f(world, params));
match thread_result_to_response::<R>(req.id.clone(), result) {
Ok(response) => Task::Response(response),
Err(_) => Task::Retry(req),
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index 09de6900c8..b3623669cc 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -291,11 +291,15 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
}
Ok(())
};
- state.task_pool.handle.spawn_with_sender(stdx::thread::ThreadIntent::Worker, move |_| {
- if let Err(e) = std::panic::catch_unwind(task) {
- tracing::error!("flycheck task panicked: {e:?}")
- }
- });
+ state.task_pool.handle.spawn_with_sender(
+ stdx::thread::ThreadIntent::Worker,
+ "flycheck",
+ move |_| {
+ if let Err(e) = std::panic::catch_unwind(task) {
+ tracing::error!("flycheck task panicked: {e:?}")
+ }
+ },
+ );
true
} else {
false
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 19c49a2300..92d44eeee8 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -397,19 +397,25 @@ impl GlobalState {
tracing::debug!(%cause, "will prime caches");
let num_worker_threads = self.config.prime_caches_num_threads();
- self.task_pool.handle.spawn_with_sender(stdx::thread::ThreadIntent::Worker, {
- let analysis = self.snapshot().analysis;
- move |sender| {
- sender.send(Task::PrimeCaches(PrimeCachesProgress::Begin)).unwrap();
- let res = analysis.parallel_prime_caches(num_worker_threads, |progress| {
- let report = PrimeCachesProgress::Report(progress);
- sender.send(Task::PrimeCaches(report)).unwrap();
- });
- sender
- .send(Task::PrimeCaches(PrimeCachesProgress::End { cancelled: res.is_err() }))
- .unwrap();
- }
- });
+ self.task_pool.handle.spawn_with_sender(
+ stdx::thread::ThreadIntent::Worker,
+ "prime_caches",
+ {
+ let analysis = self.snapshot().analysis;
+ move |sender| {
+ sender.send(Task::PrimeCaches(PrimeCachesProgress::Begin)).unwrap();
+ let res = analysis.parallel_prime_caches(num_worker_threads, |progress| {
+ let report = PrimeCachesProgress::Report(progress);
+ sender.send(Task::PrimeCaches(report)).unwrap();
+ });
+ sender
+ .send(Task::PrimeCaches(PrimeCachesProgress::End {
+ cancelled: res.is_err(),
+ }))
+ .unwrap();
+ }
+ },
+ );
}
fn update_status_or_notify(&mut self) {
@@ -796,56 +802,62 @@ impl GlobalState {
// Diagnostics are triggered by the user typing
// so we run them on a latency sensitive thread.
- self.task_pool.handle.spawn(stdx::thread::ThreadIntent::LatencySensitive, move || {
- let _p = profile::span("publish_diagnostics");
- let diagnostics = subscriptions
- .into_iter()
- .filter_map(|file_id| {
- let line_index = snapshot.file_line_index(file_id).ok()?;
- Some((
- file_id,
- line_index,
- snapshot
- .analysis
- .diagnostics(
- &snapshot.config.diagnostics(),
- ide::AssistResolveStrategy::None,
- file_id,
- )
- .ok()?,
- ))
- })
- .map(|(file_id, line_index, it)| {
- (
- file_id,
- it.into_iter()
- .map(move |d| lsp_types::Diagnostic {
- range: crate::to_proto::range(&line_index, d.range),
- severity: Some(crate::to_proto::diagnostic_severity(d.severity)),
- code: Some(lsp_types::NumberOrString::String(
- d.code.as_str().to_string(),
- )),
- code_description: Some(lsp_types::CodeDescription {
- href: lsp_types::Url::parse(&format!(
- "https://rust-analyzer.github.io/manual.html#{}",
- d.code.as_str()
- ))
- .unwrap(),
- }),
- source: Some("rust-analyzer".to_string()),
- message: d.message,
- related_information: None,
- tags: if d.unused {
- Some(vec![lsp_types::DiagnosticTag::UNNECESSARY])
- } else {
- None
- },
- data: None,
- })
- .collect::<Vec<_>>(),
- )
- });
- Task::Diagnostics(diagnostics.collect())
- });
+ self.task_pool.handle.spawn(
+ stdx::thread::ThreadIntent::LatencySensitive,
+ "publish_diagnostics",
+ move || {
+ let _p = profile::span("publish_diagnostics");
+ let diagnostics = subscriptions
+ .into_iter()
+ .filter_map(|file_id| {
+ let line_index = snapshot.file_line_index(file_id).ok()?;
+ Some((
+ file_id,
+ line_index,
+ snapshot
+ .analysis
+ .diagnostics(
+ &snapshot.config.diagnostics(),
+ ide::AssistResolveStrategy::None,
+ file_id,
+ )
+ .ok()?,
+ ))
+ })
+ .map(|(file_id, line_index, it)| {
+ (
+ file_id,
+ it.into_iter()
+ .map(move |d| lsp_types::Diagnostic {
+ range: crate::to_proto::range(&line_index, d.range),
+ severity: Some(crate::to_proto::diagnostic_severity(
+ d.severity,
+ )),
+ code: Some(lsp_types::NumberOrString::String(
+ d.code.as_str().to_string(),
+ )),
+ code_description: Some(lsp_types::CodeDescription {
+ href: lsp_types::Url::parse(&format!(
+ "https://rust-analyzer.github.io/manual.html#{}",
+ d.code.as_str()
+ ))
+ .unwrap(),
+ }),
+ source: Some("rust-analyzer".to_string()),
+ message: d.message,
+ related_information: None,
+ tags: if d.unused {
+ Some(vec![lsp_types::DiagnosticTag::UNNECESSARY])
+ } else {
+ None
+ },
+ data: None,
+ })
+ .collect::<Vec<_>>(),
+ )
+ });
+ Task::Diagnostics(diagnostics.collect())
+ },
+ );
}
}
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 6e8c8ea91a..5911e24d99 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -185,7 +185,7 @@ impl GlobalState {
pub(crate) fn fetch_workspaces(&mut self, cause: Cause) {
tracing::info!(%cause, "will fetch workspaces");
- self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, {
+ self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, "fetch_workspaces", {
let linked_projects = self.config.linked_projects();
let detached_files = self.config.detached_files().to_vec();
let cargo_config = self.config.cargo();
@@ -260,19 +260,25 @@ impl GlobalState {
tracing::info!(%cause, "will fetch build data");
let workspaces = Arc::clone(&self.workspaces);
let config = self.config.cargo();
- self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {
- sender.send(Task::FetchBuildData(BuildDataProgress::Begin)).unwrap();
+ self.task_pool.handle.spawn_with_sender(
+ ThreadIntent::Worker,
+ "fetch_build_data",
+ move |sender| {
+ sender.send(Task::FetchBuildData(BuildDataProgress::Begin)).unwrap();
- let progress = {
- let sender = sender.clone();
- move |msg| {
- sender.send(Task::FetchBuildData(BuildDataProgress::Report(msg))).unwrap()
- }
- };
- let res = ProjectWorkspace::run_all_build_scripts(&workspaces, &config, &progress);
+ let progress = {
+ let sender = sender.clone();
+ move |msg| {
+ sender.send(Task::FetchBuildData(BuildDataProgress::Report(msg))).unwrap()
+ }
+ };
+ let res = ProjectWorkspace::run_all_build_scripts(&workspaces, &config, &progress);
- sender.send(Task::FetchBuildData(BuildDataProgress::End((workspaces, res)))).unwrap();
- });
+ sender
+ .send(Task::FetchBuildData(BuildDataProgress::End((workspaces, res))))
+ .unwrap();
+ },
+ );
}
pub(crate) fn fetch_proc_macros(&mut self, cause: Cause, paths: Vec<ProcMacroPaths>) {
@@ -280,50 +286,54 @@ impl GlobalState {
let dummy_replacements = self.config.dummy_replacements().clone();
let proc_macro_clients = self.proc_macro_clients.clone();
- self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {
- sender.send(Task::LoadProcMacros(ProcMacroProgress::Begin)).unwrap();
+ self.task_pool.handle.spawn_with_sender(
+ ThreadIntent::Worker,
+ "fetch_proc_macros",
+ move |sender| {
+ sender.send(Task::LoadProcMacros(ProcMacroProgress::Begin)).unwrap();
+
+ let dummy_replacements = &dummy_replacements;
+ let progress = {
+ let sender = sender.clone();
+ &move |msg| {
+ sender.send(Task::LoadProcMacros(ProcMacroProgress::Report(msg))).unwrap()
+ }
+ };
- let dummy_replacements = &dummy_replacements;
- let progress = {
- let sender = sender.clone();
- &move |msg| {
- sender.send(Task::LoadProcMacros(ProcMacroProgress::Report(msg))).unwrap()
+ let mut res = FxHashMap::default();
+ let chain = proc_macro_clients
+ .iter()
+ .map(|res| res.as_ref().map_err(|e| e.to_string()))
+ .chain(iter::repeat_with(|| Err("Proc macros servers are not running".into())));
+ for (client, paths) in chain.zip(paths) {
+ res.extend(paths.into_iter().map(move |(crate_id, res)| {
+ (
+ crate_id,
+ res.map_or_else(
+ |_| Err("proc macro crate is missing dylib".to_owned()),
+ |(crate_name, path)| {
+ progress(path.display().to_string());
+ client.as_ref().map_err(Clone::clone).and_then(|client| {
+ load_proc_macro(
+ client,
+ &path,
+ crate_name
+ .as_deref()
+ .and_then(|crate_name| {
+ dummy_replacements.get(crate_name).map(|v| &**v)
+ })
+ .unwrap_or_default(),
+ )
+ })
+ },
+ ),
+ )
+ }));
}
- };
-
- let mut res = FxHashMap::default();
- let chain = proc_macro_clients
- .iter()
- .map(|res| res.as_ref().map_err(|e| e.to_string()))
- .chain(iter::repeat_with(|| Err("Proc macros servers are not running".into())));
- for (client, paths) in chain.zip(paths) {
- res.extend(paths.into_iter().map(move |(crate_id, res)| {
- (
- crate_id,
- res.map_or_else(
- |_| Err("proc macro crate is missing dylib".to_owned()),
- |(crate_name, path)| {
- progress(path.display().to_string());
- client.as_ref().map_err(Clone::clone).and_then(|client| {
- load_proc_macro(
- client,
- &path,
- crate_name
- .as_deref()
- .and_then(|crate_name| {
- dummy_replacements.get(crate_name).map(|v| &**v)
- })
- .unwrap_or_default(),
- )
- })
- },
- ),
- )
- }));
- }
- sender.send(Task::LoadProcMacros(ProcMacroProgress::End(res))).unwrap();
- });
+ sender.send(Task::LoadProcMacros(ProcMacroProgress::End(res))).unwrap();
+ },
+ );
}
pub(crate) fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
diff --git a/crates/rust-analyzer/src/task_pool.rs b/crates/rust-analyzer/src/task_pool.rs
index a5a10e8691..823210980f 100644
--- a/crates/rust-analyzer/src/task_pool.rs
+++ b/crates/rust-analyzer/src/task_pool.rs
@@ -14,25 +14,41 @@ impl<T> TaskPool<T> {
TaskPool { sender, pool: Pool::new(threads) }
}
- pub(crate) fn spawn<F>(&mut self, intent: ThreadIntent, task: F)
- where
+ pub(crate) fn spawn<F>(
+ &mut self,
+ intent: ThreadIntent,
+ panic_context: impl Into<String>,
+ task: F,
+ ) where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
+ let panic_context = panic_context.into();
self.pool.spawn(intent, {
let sender = self.sender.clone();
- move || sender.send(task()).unwrap()
+ move || {
+ let _pctx = stdx::panic_context::enter(panic_context);
+ sender.send(task()).unwrap()
+ }
})
}
- pub(crate) fn spawn_with_sender<F>(&mut self, intent: ThreadIntent, task: F)
- where
+ pub(crate) fn spawn_with_sender<F>(
+ &mut self,
+ intent: ThreadIntent,
+ panic_context: impl Into<String>,
+ task: F,
+ ) where
F: FnOnce(Sender<T>) + Send + 'static,
T: Send + 'static,
{
+ let panic_context = panic_context.into();
self.pool.spawn(intent, {
let sender = self.sender.clone();
- move || task(sender)
+ move || {
+ let _pctx = stdx::panic_context::enter(panic_context);
+ task(sender)
+ }
})
}