Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21555 from Veykril/push-vlrmztunpmtm
fix: Fix diagnostics being leaked when diagnostics panic
Lukas Wirth 3 months ago
parent 2e35358 · parent 97ef0b1 · commit eb05888
-rw-r--r--crates/rust-analyzer/src/diagnostics.rs60
-rw-r--r--crates/rust-analyzer/src/main_loop.rs18
2 files changed, 43 insertions, 35 deletions
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs
index 712960f13d..8d0f52433e 100644
--- a/crates/rust-analyzer/src/diagnostics.rs
+++ b/crates/rust-analyzer/src/diagnostics.rs
@@ -289,34 +289,40 @@ pub(crate) fn fetch_native_diagnostics(
let mut diagnostics = subscriptions[slice]
.iter()
.copied()
- .filter_map(|file_id| {
- let line_index = snapshot.file_line_index(file_id).ok()?;
- let source_root = snapshot.analysis.source_root_id(file_id).ok()?;
-
- let config = &snapshot.config.diagnostics(Some(source_root));
- let diagnostics = match kind {
- NativeDiagnosticsFetchKind::Syntax => {
- snapshot.analysis.syntax_diagnostics(config, file_id).ok()?
- }
-
- NativeDiagnosticsFetchKind::Semantic if config.enabled => snapshot
- .analysis
- .semantic_diagnostics(config, ide::AssistResolveStrategy::None, file_id)
- .ok()?,
- NativeDiagnosticsFetchKind::Semantic => return None,
- };
- let diagnostics = diagnostics
- .into_iter()
- .filter_map(|d| {
- if d.range.file_id == file_id {
- Some(convert_diagnostic(&line_index, d))
- } else {
- odd_ones.push(d);
- None
+ .map(|file_id| {
+ let diagnostics = (|| {
+ let line_index = snapshot.file_line_index(file_id).ok()?;
+ let source_root = snapshot.analysis.source_root_id(file_id).ok()?;
+
+ let config = &snapshot.config.diagnostics(Some(source_root));
+ let diagnostics = match kind {
+ NativeDiagnosticsFetchKind::Syntax => {
+ snapshot.analysis.syntax_diagnostics(config, file_id).ok()?
}
- })
- .collect::<Vec<_>>();
- Some((file_id, diagnostics))
+
+ NativeDiagnosticsFetchKind::Semantic if config.enabled => snapshot
+ .analysis
+ .semantic_diagnostics(config, ide::AssistResolveStrategy::None, file_id)
+ .ok()?,
+ NativeDiagnosticsFetchKind::Semantic => return None,
+ };
+ Some(
+ diagnostics
+ .into_iter()
+ .filter_map(|d| {
+ if d.range.file_id == file_id {
+ Some(convert_diagnostic(&line_index, d))
+ } else {
+ odd_ones.push(d);
+ None
+ }
+ })
+ .collect::<Vec<_>>(),
+ )
+ })()
+ .unwrap_or_default();
+
+ (file_id, diagnostics)
})
.collect::<Vec<_>>();
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index f5cead5d8f..64decc9e0d 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -666,31 +666,33 @@ impl GlobalState {
move |sender| {
// We aren't observing the semantics token cache here
let snapshot = AssertUnwindSafe(&snapshot);
- let Ok(diags) = std::panic::catch_unwind(|| {
+ let diags = std::panic::catch_unwind(|| {
fetch_native_diagnostics(
&snapshot,
subscriptions.clone(),
slice.clone(),
NativeDiagnosticsFetchKind::Syntax,
)
- }) else {
- return;
- };
+ })
+ .unwrap_or_else(|_| {
+ subscriptions.iter().map(|&id| (id, Vec::new())).collect::<Vec<_>>()
+ });
sender
.send(Task::Diagnostics(DiagnosticsTaskKind::Syntax(generation, diags)))
.unwrap();
if fetch_semantic {
- let Ok(diags) = std::panic::catch_unwind(|| {
+ let diags = std::panic::catch_unwind(|| {
fetch_native_diagnostics(
&snapshot,
subscriptions.clone(),
slice.clone(),
NativeDiagnosticsFetchKind::Semantic,
)
- }) else {
- return;
- };
+ })
+ .unwrap_or_else(|_| {
+ subscriptions.iter().map(|&id| (id, Vec::new())).collect::<Vec<_>>()
+ });
sender
.send(Task::Diagnostics(DiagnosticsTaskKind::Semantic(
generation, diags,