Merge pull request #21571 from Wilfred/check_type_names
fix: Stale diagnostics with rust-project.json and rustc JSON
This commit is contained in:
commit
36058bfc0f
1 changed files with 71 additions and 36 deletions
|
|
@ -421,11 +421,17 @@ struct FlycheckActor {
|
|||
diagnostics_received: DiagnosticsReceived,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum DiagnosticsReceived {
|
||||
Yes,
|
||||
No,
|
||||
YesAndClearedForAll,
|
||||
/// We started a flycheck, but we haven't seen any diagnostics yet.
|
||||
NotYet,
|
||||
/// We received a non-zero number of diagnostics from rustc or clippy (via
|
||||
/// cargo or custom check command). This means there were errors or
|
||||
/// warnings.
|
||||
AtLeastOne,
|
||||
/// We received a non-zero number of diagnostics, and the scope is
|
||||
/// workspace, so we've discarded the previous workspace diagnostics.
|
||||
AtLeastOneAndClearedWorkspace,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
|
|
@ -522,7 +528,7 @@ impl FlycheckActor {
|
|||
command_handle: None,
|
||||
command_receiver: None,
|
||||
diagnostics_cleared_for: Default::default(),
|
||||
diagnostics_received: DiagnosticsReceived::No,
|
||||
diagnostics_received: DiagnosticsReceived::NotYet,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -641,7 +647,7 @@ impl FlycheckActor {
|
|||
error
|
||||
);
|
||||
}
|
||||
if self.diagnostics_received == DiagnosticsReceived::No {
|
||||
if self.diagnostics_received == DiagnosticsReceived::NotYet {
|
||||
tracing::trace!(flycheck_id = self.id, "clearing diagnostics");
|
||||
// We finished without receiving any diagnostics.
|
||||
// Clear everything for good measure
|
||||
|
|
@ -735,41 +741,70 @@ impl FlycheckActor {
|
|||
flycheck_id = self.id,
|
||||
message = diagnostic.message,
|
||||
package_id = package_id.as_ref().map(|it| it.as_str()),
|
||||
scope = ?self.scope,
|
||||
"diagnostic received"
|
||||
);
|
||||
if self.diagnostics_received == DiagnosticsReceived::No {
|
||||
self.diagnostics_received = DiagnosticsReceived::Yes;
|
||||
}
|
||||
if let Some(package_id) = &package_id {
|
||||
if self.diagnostics_cleared_for.insert(package_id.clone()) {
|
||||
tracing::trace!(
|
||||
flycheck_id = self.id,
|
||||
package_id = package_id.as_str(),
|
||||
"clearing diagnostics"
|
||||
);
|
||||
self.send(FlycheckMessage::ClearDiagnostics {
|
||||
|
||||
match &self.scope {
|
||||
FlycheckScope::Workspace => {
|
||||
if self.diagnostics_received == DiagnosticsReceived::NotYet {
|
||||
self.send(FlycheckMessage::ClearDiagnostics {
|
||||
id: self.id,
|
||||
kind: ClearDiagnosticsKind::All(ClearScope::Workspace),
|
||||
});
|
||||
|
||||
self.diagnostics_received =
|
||||
DiagnosticsReceived::AtLeastOneAndClearedWorkspace;
|
||||
}
|
||||
|
||||
if let Some(package_id) = package_id {
|
||||
tracing::warn!(
|
||||
"Ignoring package label {:?} and applying diagnostics to the whole workspace",
|
||||
package_id
|
||||
);
|
||||
}
|
||||
|
||||
self.send(FlycheckMessage::AddDiagnostic {
|
||||
id: self.id,
|
||||
kind: ClearDiagnosticsKind::All(ClearScope::Package(
|
||||
package_id.clone(),
|
||||
)),
|
||||
generation: self.generation,
|
||||
package_id: None,
|
||||
workspace_root: self.root.clone(),
|
||||
diagnostic,
|
||||
});
|
||||
}
|
||||
FlycheckScope::Package { package: flycheck_package, .. } => {
|
||||
if self.diagnostics_received == DiagnosticsReceived::NotYet {
|
||||
self.diagnostics_received = DiagnosticsReceived::AtLeastOne;
|
||||
}
|
||||
|
||||
// If the package has been set in the diagnostic JSON, respect that. Otherwise, use the
|
||||
// package that the current flycheck is scoped to. This is useful when a project is
|
||||
// directly using rustc for its checks (e.g. custom check commands in rust-project.json).
|
||||
let package_id = package_id.unwrap_or(flycheck_package.clone());
|
||||
|
||||
if self.diagnostics_cleared_for.insert(package_id.clone()) {
|
||||
tracing::trace!(
|
||||
flycheck_id = self.id,
|
||||
package_id = package_id.as_str(),
|
||||
"clearing diagnostics"
|
||||
);
|
||||
self.send(FlycheckMessage::ClearDiagnostics {
|
||||
id: self.id,
|
||||
kind: ClearDiagnosticsKind::All(ClearScope::Package(
|
||||
package_id.clone(),
|
||||
)),
|
||||
});
|
||||
}
|
||||
|
||||
self.send(FlycheckMessage::AddDiagnostic {
|
||||
id: self.id,
|
||||
generation: self.generation,
|
||||
package_id: Some(package_id),
|
||||
workspace_root: self.root.clone(),
|
||||
diagnostic,
|
||||
});
|
||||
}
|
||||
} else if self.diagnostics_received
|
||||
!= DiagnosticsReceived::YesAndClearedForAll
|
||||
{
|
||||
self.diagnostics_received = DiagnosticsReceived::YesAndClearedForAll;
|
||||
self.send(FlycheckMessage::ClearDiagnostics {
|
||||
id: self.id,
|
||||
kind: ClearDiagnosticsKind::All(ClearScope::Workspace),
|
||||
});
|
||||
}
|
||||
self.send(FlycheckMessage::AddDiagnostic {
|
||||
id: self.id,
|
||||
generation: self.generation,
|
||||
package_id,
|
||||
workspace_root: self.root.clone(),
|
||||
diagnostic,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -793,7 +828,7 @@ impl FlycheckActor {
|
|||
|
||||
fn clear_diagnostics_state(&mut self) {
|
||||
self.diagnostics_cleared_for.clear();
|
||||
self.diagnostics_received = DiagnosticsReceived::No;
|
||||
self.diagnostics_received = DiagnosticsReceived::NotYet;
|
||||
}
|
||||
|
||||
fn explicit_check_command(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue