mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 05:08:52 +00:00
Merge pull request #18826 from Veykril/push-qnsqormwlwqm
fix: Clear flycheck diagnostics per package properly
This commit is contained in:
commit
ce6053cbd6
1 changed files with 21 additions and 36 deletions
|
@ -1,10 +1,11 @@
|
||||||
//! Flycheck provides the functionality needed to run `cargo check` to provide
|
//! Flycheck provides the functionality needed to run `cargo check` to provide
|
||||||
//! LSP diagnostics based on the output of the command.
|
//! LSP diagnostics based on the output of the command.
|
||||||
|
|
||||||
use std::{fmt, io, mem, process::Command, time::Duration};
|
use std::{fmt, io, process::Command, time::Duration};
|
||||||
|
|
||||||
use cargo_metadata::PackageId;
|
use cargo_metadata::PackageId;
|
||||||
use crossbeam_channel::{select_biased, unbounded, Receiver, Sender};
|
use crossbeam_channel::{select_biased, unbounded, Receiver, Sender};
|
||||||
|
use ide_db::FxHashSet;
|
||||||
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::Deserialize as _;
|
use serde::Deserialize as _;
|
||||||
|
@ -231,13 +232,7 @@ struct FlycheckActor {
|
||||||
command_handle: Option<CommandHandle<CargoCheckMessage>>,
|
command_handle: Option<CommandHandle<CargoCheckMessage>>,
|
||||||
/// The receiver side of the channel mentioned above.
|
/// The receiver side of the channel mentioned above.
|
||||||
command_receiver: Option<Receiver<CargoCheckMessage>>,
|
command_receiver: Option<Receiver<CargoCheckMessage>>,
|
||||||
package_status: FxHashMap<Arc<PackageId>, DiagnosticReceived>,
|
diagnostics_cleared_for: FxHashSet<Arc<PackageId>>,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
|
||||||
enum DiagnosticReceived {
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
@ -267,7 +262,7 @@ impl FlycheckActor {
|
||||||
manifest_path,
|
manifest_path,
|
||||||
command_handle: None,
|
command_handle: None,
|
||||||
command_receiver: None,
|
command_receiver: None,
|
||||||
package_status: FxHashMap::default(),
|
diagnostics_cleared_for: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,16 +339,16 @@ impl FlycheckActor {
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if self.package_status.is_empty() {
|
if self.diagnostics_cleared_for.is_empty() {
|
||||||
tracing::trace!(flycheck_id = self.id, "clearing diagnostics");
|
tracing::trace!(flycheck_id = self.id, "clearing diagnostics");
|
||||||
// We finished without receiving any diagnostics.
|
// We finished without receiving any diagnostics.
|
||||||
// That means all of them are stale.
|
// Clear everything for good measure
|
||||||
self.send(FlycheckMessage::ClearDiagnostics {
|
self.send(FlycheckMessage::ClearDiagnostics {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
package_id: None,
|
package_id: None,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.send_clear_diagnostics();
|
self.diagnostics_cleared_for.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.report_progress(Progress::DidFinish(res));
|
self.report_progress(Progress::DidFinish(res));
|
||||||
|
@ -367,9 +362,18 @@ impl FlycheckActor {
|
||||||
"artifact received"
|
"artifact received"
|
||||||
);
|
);
|
||||||
self.report_progress(Progress::DidCheckCrate(msg.target.name));
|
self.report_progress(Progress::DidCheckCrate(msg.target.name));
|
||||||
self.package_status
|
let package_id = Arc::new(msg.package_id);
|
||||||
.entry(Arc::new(msg.package_id))
|
if self.diagnostics_cleared_for.insert(package_id.clone()) {
|
||||||
.or_insert(DiagnosticReceived::No);
|
tracing::trace!(
|
||||||
|
flycheck_id = self.id,
|
||||||
|
package_id = package_id.repr,
|
||||||
|
"clearing diagnostics"
|
||||||
|
);
|
||||||
|
self.send(FlycheckMessage::ClearDiagnostics {
|
||||||
|
id: self.id,
|
||||||
|
package_id: Some(package_id),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CargoCheckMessage::Diagnostic { diagnostic, package_id } => {
|
CargoCheckMessage::Diagnostic { diagnostic, package_id } => {
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
|
@ -379,10 +383,7 @@ impl FlycheckActor {
|
||||||
"diagnostic received"
|
"diagnostic received"
|
||||||
);
|
);
|
||||||
if let Some(package_id) = &package_id {
|
if let Some(package_id) = &package_id {
|
||||||
if let None | Some(DiagnosticReceived::No) = self
|
if self.diagnostics_cleared_for.insert(package_id.clone()) {
|
||||||
.package_status
|
|
||||||
.insert(package_id.clone(), DiagnosticReceived::Yes)
|
|
||||||
{
|
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
flycheck_id = self.id,
|
flycheck_id = self.id,
|
||||||
package_id = package_id.repr,
|
package_id = package_id.repr,
|
||||||
|
@ -417,23 +418,7 @@ impl FlycheckActor {
|
||||||
command_handle.cancel();
|
command_handle.cancel();
|
||||||
self.command_receiver.take();
|
self.command_receiver.take();
|
||||||
self.report_progress(Progress::DidCancel);
|
self.report_progress(Progress::DidCancel);
|
||||||
self.send_clear_diagnostics();
|
self.diagnostics_cleared_for.clear();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_clear_diagnostics(&mut self) {
|
|
||||||
for (package_id, status) in mem::take(&mut self.package_status) {
|
|
||||||
if let DiagnosticReceived::No = status {
|
|
||||||
tracing::trace!(
|
|
||||||
flycheck_id = self.id,
|
|
||||||
package_id = package_id.repr,
|
|
||||||
"clearing diagnostics"
|
|
||||||
);
|
|
||||||
self.send(FlycheckMessage::ClearDiagnostics {
|
|
||||||
id: self.id,
|
|
||||||
package_id: Some(package_id),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue