Skip to content

Commit 92ba1cc

Browse files
authored
Merge pull request #20459 from rust-lang/veykril/push-pwzyxwuozkrq
Track diagnostic generations per package
2 parents 4d7b904 + e87a2fc commit 92ba1cc

File tree

1 file changed

+32
-24
lines changed

1 file changed

+32
-24
lines changed

crates/rust-analyzer/src/diagnostics.rs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,15 @@ pub struct DiagnosticsMapConfig {
2626

2727
pub(crate) type DiagnosticsGeneration = usize;
2828

29-
#[derive(Debug, Clone)]
29+
#[derive(Debug, Clone, Default)]
3030
pub(crate) struct WorkspaceFlycheckDiagnostic {
31-
pub(crate) generation: DiagnosticsGeneration,
32-
pub(crate) per_package:
33-
FxHashMap<Option<Arc<PackageId>>, FxHashMap<FileId, Vec<lsp_types::Diagnostic>>>,
31+
pub(crate) per_package: FxHashMap<Option<Arc<PackageId>>, PackageFlycheckDiagnostic>,
3432
}
3533

36-
impl WorkspaceFlycheckDiagnostic {
37-
fn new(generation: DiagnosticsGeneration) -> Self {
38-
WorkspaceFlycheckDiagnostic { generation, per_package: Default::default() }
39-
}
34+
#[derive(Debug, Clone)]
35+
pub(crate) struct PackageFlycheckDiagnostic {
36+
generation: DiagnosticsGeneration,
37+
per_file: FxHashMap<FileId, Vec<lsp_types::Diagnostic>>,
4038
}
4139

4240
#[derive(Debug, Default, Clone)]
@@ -68,7 +66,7 @@ impl DiagnosticCollection {
6866
let Some(check) = self.check.get_mut(flycheck_id) else {
6967
return;
7068
};
71-
self.changes.extend(check.per_package.drain().flat_map(|(_, v)| v.into_keys()));
69+
self.changes.extend(check.per_package.drain().flat_map(|(_, v)| v.per_file.into_keys()));
7270
if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
7371
fixes.clear();
7472
}
@@ -79,7 +77,7 @@ impl DiagnosticCollection {
7977
self.changes.extend(
8078
self.check
8179
.iter_mut()
82-
.flat_map(|it| it.per_package.drain().flat_map(|(_, v)| v.into_keys())),
80+
.flat_map(|it| it.per_package.drain().flat_map(|(_, v)| v.per_file.into_keys())),
8381
)
8482
}
8583

@@ -93,7 +91,7 @@ impl DiagnosticCollection {
9391
};
9492
let package_id = Some(package_id);
9593
if let Some(checks) = check.per_package.remove(&package_id) {
96-
self.changes.extend(checks.into_keys());
94+
self.changes.extend(checks.per_file.into_keys());
9795
}
9896
if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
9997
fixes.remove(&package_id);
@@ -105,8 +103,20 @@ impl DiagnosticCollection {
105103
flycheck_id: usize,
106104
generation: DiagnosticsGeneration,
107105
) {
108-
if self.check.get(flycheck_id).is_some_and(|it| it.generation < generation) {
109-
self.clear_check(flycheck_id);
106+
if let Some(flycheck) = self.check.get_mut(flycheck_id) {
107+
let mut packages = vec![];
108+
self.changes.extend(
109+
flycheck
110+
.per_package
111+
.extract_if(|_, v| v.generation < generation)
112+
.inspect(|(package_id, _)| packages.push(package_id.clone()))
113+
.flat_map(|(_, v)| v.per_file.into_keys()),
114+
);
115+
if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) {
116+
for package in packages {
117+
fixes.remove(&package);
118+
}
119+
}
110120
}
111121
}
112122

@@ -126,21 +136,19 @@ impl DiagnosticCollection {
126136
fix: Option<Box<Fix>>,
127137
) {
128138
if self.check.len() <= flycheck_id {
129-
self.check
130-
.resize_with(flycheck_id + 1, || WorkspaceFlycheckDiagnostic::new(generation));
139+
self.check.resize_with(flycheck_id + 1, WorkspaceFlycheckDiagnostic::default);
131140
}
132141

142+
let check = &mut self.check[flycheck_id];
143+
let package = check.per_package.entry(package_id.clone()).or_insert_with(|| {
144+
PackageFlycheckDiagnostic { generation, per_file: FxHashMap::default() }
145+
});
133146
// Getting message from old generation. Might happen in restarting checks.
134-
if self.check[flycheck_id].generation > generation {
147+
if package.generation > generation {
135148
return;
136149
}
137-
self.check[flycheck_id].generation = generation;
138-
let diagnostics = self.check[flycheck_id]
139-
.per_package
140-
.entry(package_id.clone())
141-
.or_default()
142-
.entry(file_id)
143-
.or_default();
150+
package.generation = generation;
151+
let diagnostics = package.per_file.entry(file_id).or_default();
144152
for existing_diagnostic in diagnostics.iter() {
145153
if are_diagnostics_equal(existing_diagnostic, &diagnostic) {
146154
return;
@@ -210,7 +218,7 @@ impl DiagnosticCollection {
210218
.check
211219
.iter()
212220
.flat_map(|it| it.per_package.values())
213-
.filter_map(move |it| it.get(&file_id))
221+
.filter_map(move |it| it.per_file.get(&file_id))
214222
.flatten();
215223
native_syntax.chain(native_semantic).chain(check)
216224
}

0 commit comments

Comments
 (0)