diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index e86944eeb352..73d8246bca03 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -277,6 +277,7 @@ pub struct CrateData { pub root_file_id: FileId, pub edition: Edition, pub version: Option, + pub package_id: Option, /// A name used in the package's project declaration: for Cargo projects, /// its `[package].name` can be different for other project types or even /// absent (a dummy crate for the code snippet, for example). @@ -357,6 +358,7 @@ impl CrateGraph { edition: Edition, display_name: Option, version: Option, + package_id: Option, cfg_options: Arc, potential_cfg_options: Option>, mut env: Env, @@ -368,6 +370,7 @@ impl CrateGraph { root_file_id, edition, version, + package_id, display_name, cfg_options, potential_cfg_options, @@ -690,6 +693,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -701,6 +705,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -712,6 +717,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -737,6 +743,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -748,6 +755,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -770,6 +778,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -781,6 +790,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -792,6 +802,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -814,6 +825,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -825,6 +837,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 9bd7d38f0a64..70f6c473c63c 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -439,6 +439,13 @@ impl DefMap { .map(|(id, _data)| id) } + pub fn files(&self) -> impl Iterator + '_ { + self.modules + .iter() + .filter_map(|(_id, data)| data.origin.file_id()) + .map(EditionedFileId::file_id) + } + pub fn modules(&self) -> impl Iterator + '_ { self.modules.iter() } diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index c13fc843568c..fcce8ad36b70 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -61,7 +61,7 @@ use std::{iter, panic::UnwindSafe}; use cfg::CfgOptions; use fetch_crates::CrateInfo; -use hir::{sym, ChangeWithProcMacros}; +use hir::{db::DefDatabase, sym, ChangeWithProcMacros}; use ide_db::{ base_db::{ ra_salsa::{self, ParallelDatabase}, @@ -248,6 +248,7 @@ impl Analysis { Edition::CURRENT, None, None, + None, Arc::new(cfg_options), None, Env::default(), @@ -593,6 +594,23 @@ impl Analysis { self.with_db(|db| parent_module::crates_for(db, file_id)) } + /// Returns files that belong to this crate + pub fn files_for(&self, crate_id: CrateId) -> Cancellable> { + self.with_db(|db| db.crate_def_map(crate_id).files().collect()) + } + + /// Returns the crate with the given package id + pub fn crate_with_id(&self, package_id: &str) -> Cancellable> { + self.with_db(|db| { + let graph = db.crate_graph(); + let id = graph.iter().find(|id| { + let crate_data = &graph[*id]; + crate_data.package_id.as_deref() == Some(package_id) + }); + id + }) + } + /// Returns crates this file belongs too. pub fn transitive_rev_deps(&self, crate_id: CrateId) -> Cancellable> { self.with_db(|db| db.crate_graph().transitive_rev_deps(crate_id).collect()) diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs index 9e823daa2bec..66cc629d5a98 100644 --- a/crates/ide/src/status.rs +++ b/crates/ide/src/status.rs @@ -62,6 +62,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { root_file_id, edition, version, + package_id, display_name, cfg_options, potential_cfg_options, @@ -81,6 +82,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { format_to!(buf, " Root module file id: {}\n", root_file_id.index()); format_to!(buf, " Edition: {}\n", edition); format_to!(buf, " Version: {}\n", version.as_deref().unwrap_or("n/a")); + format_to!(buf, " Package Id: {}\n", package_id.as_deref().unwrap_or("n/a")); format_to!(buf, " Enabled cfgs: {:?}\n", cfg_options); format_to!(buf, " Potential cfgs: {:?}\n", potential_cfg_options); format_to!(buf, " Env: {:?}\n", env); diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 71ddee309100..2955c8e8aa03 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -944,6 +944,7 @@ fn project_json_to_crate_graph( *edition, display_name.clone(), version.clone(), + None, Arc::new(cfg_options), None, env, @@ -1222,6 +1223,7 @@ fn detached_file_to_crate_graph( Edition::CURRENT, display_name.clone(), None, + None, cfg_options.clone(), None, Env::default(), @@ -1389,6 +1391,7 @@ fn add_target_crate_root( edition, Some(CrateDisplayName::from_canonical_name(cargo_name)), Some(pkg.version.to_string()), + Some(pkg.id.to_string()), Arc::new(cfg_options), potential_cfg_options.map(Arc::new), env, @@ -1528,6 +1531,7 @@ fn sysroot_to_crate_graph( Edition::CURRENT_FIXME, Some(display_name), None, + None, cfg_options.clone(), None, Env::default(), diff --git a/crates/project-model/test_data/output/cargo_hello_world_project_model.txt b/crates/project-model/test_data/output/cargo_hello_world_project_model.txt index 880e90c52a54..8bb464621571 100644 --- a/crates/project-model/test_data/output/cargo_hello_world_project_model.txt +++ b/crates/project-model/test_data/output/cargo_hello_world_project_model.txt @@ -7,6 +7,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -70,6 +73,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -141,6 +147,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -212,6 +221,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -283,6 +295,9 @@ version: Some( "0.2.98", ), + package_id: Some( + "libc 0.2.98 (registry+https://github.com/rust-lang/crates.io-index)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( diff --git a/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt b/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt index 880e90c52a54..8bb464621571 100644 --- a/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt +++ b/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt @@ -7,6 +7,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -70,6 +73,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -141,6 +147,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -212,6 +221,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -283,6 +295,9 @@ version: Some( "0.2.98", ), + package_id: Some( + "libc 0.2.98 (registry+https://github.com/rust-lang/crates.io-index)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( diff --git a/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt b/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt index 7746acd225e3..33d6c485212a 100644 --- a/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt +++ b/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt @@ -7,6 +7,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -69,6 +72,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -139,6 +145,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -209,6 +218,9 @@ version: Some( "0.1.0", ), + package_id: Some( + "hello-world 0.1.0 (path+file://$ROOT$hello-world)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -279,6 +291,9 @@ version: Some( "0.2.98", ), + package_id: Some( + "libc 0.2.98 (registry+https://github.com/rust-lang/crates.io-index)", + ), display_name: Some( CrateDisplayName { crate_name: CrateName( diff --git a/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 90f41a9c2fc8..65a72c7d564a 100644 --- a/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -5,6 +5,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -45,6 +46,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -76,6 +78,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -107,6 +110,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -138,6 +142,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -186,6 +191,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -217,6 +223,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -313,6 +320,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -344,6 +352,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -375,6 +384,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -406,6 +416,7 @@ ), edition: Edition2018, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -483,6 +494,7 @@ ), edition: Edition2018, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( diff --git a/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index a0e14b8fcb22..0d48359bbdbc 100644 --- a/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -5,6 +5,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -45,6 +46,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -76,6 +78,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -107,6 +110,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -138,6 +142,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -186,6 +191,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -217,6 +223,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -313,6 +320,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -344,6 +352,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -375,6 +384,7 @@ ), edition: Edition2021, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( @@ -406,6 +416,7 @@ ), edition: Edition2018, version: None, + package_id: None, display_name: Some( CrateDisplayName { crate_name: CrateName( diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs index 22910ee4c68a..b868b3ccd052 100644 --- a/crates/rust-analyzer/src/diagnostics.rs +++ b/crates/rust-analyzer/src/diagnostics.rs @@ -24,6 +24,7 @@ pub struct DiagnosticsMapConfig { } pub(crate) type DiagnosticsGeneration = usize; +pub(crate) type FlycheckGeneration = usize; #[derive(Debug, Default, Clone)] pub(crate) struct DiagnosticCollection { @@ -31,7 +32,8 @@ pub(crate) struct DiagnosticCollection { pub(crate) native_syntax: IntMap)>, pub(crate) native_semantic: IntMap)>, // FIXME: should be Vec - pub(crate) check: IntMap>>, + pub(crate) check: + IntMap)>>, pub(crate) check_fixes: CheckFixes, changes: IntSet, /// Counter for supplying a new generation number for diagnostics. @@ -49,12 +51,28 @@ pub(crate) struct Fix { } impl DiagnosticCollection { - pub(crate) fn clear_check(&mut self, flycheck_id: usize) { - if let Some(it) = Arc::make_mut(&mut self.check_fixes).get_mut(&flycheck_id) { - it.clear(); - } - if let Some(it) = self.check.get_mut(&flycheck_id) { - self.changes.extend(it.drain().map(|(key, _value)| key)); + pub(crate) fn clear_previous_check( + &mut self, + flycheck_id: usize, + flycheck_gen: FlycheckGeneration, + ) { + let mut maybe_fixes = Arc::make_mut(&mut self.check_fixes).get_mut(&flycheck_id); + let Some(it) = self.check.get_mut(&flycheck_id) else { + return; + }; + + let file_ids: Vec = it.keys().cloned().collect(); + for file_id in file_ids { + let Some((generation, _)) = it.get_mut(&file_id) else { + continue; + }; + if *generation != flycheck_gen { + it.remove(&file_id); + if let Some(ref mut fixes) = maybe_fixes { + fixes.remove(&file_id); + } + self.changes.insert(file_id); + } } } @@ -70,14 +88,40 @@ impl DiagnosticCollection { self.changes.insert(file_id); } + pub(crate) fn clear_file_previous_check( + &mut self, + flycheck_id: usize, + flycheck_gen: FlycheckGeneration, + file_id: FileId, + ) { + let Some(check) = self.check.get_mut(&flycheck_id) else { + return; + }; + let Some((generation, diagnostics)) = check.get_mut(&file_id) else { + return; + }; + if *generation != flycheck_gen { + let check_fixes = Arc::make_mut(&mut self.check_fixes); + check_fixes.entry(flycheck_id).or_default().entry(file_id).or_default().clear(); + diagnostics.clear(); + self.changes.insert(file_id); + } + } + pub(crate) fn add_check_diagnostic( &mut self, flycheck_id: usize, + flycheck_gen: FlycheckGeneration, file_id: FileId, diagnostic: lsp_types::Diagnostic, fix: Option>, ) { - let diagnostics = self.check.entry(flycheck_id).or_default().entry(file_id).or_default(); + let (generation, diagnostics) = + self.check.entry(flycheck_id).or_default().entry(file_id).or_default(); + if *generation != flycheck_gen { + *generation = flycheck_gen; + diagnostics.clear(); + } for existing_diagnostic in diagnostics.iter() { if are_diagnostics_equal(existing_diagnostic, &diagnostic) { return; @@ -135,7 +179,11 @@ impl DiagnosticCollection { ) -> impl Iterator { let native_syntax = self.native_syntax.get(&file_id).into_iter().flat_map(|(_, d)| d); let native_semantic = self.native_semantic.get(&file_id).into_iter().flat_map(|(_, d)| d); - let check = self.check.values().filter_map(move |it| it.get(&file_id)).flatten(); + let check = self + .check + .values() + .filter_map(move |it| it.get(&file_id).map(|(_, diags)| diags)) + .flatten(); native_syntax.chain(native_semantic).chain(check) } diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs index b035d779a7d5..5300c659b9df 100644 --- a/crates/rust-analyzer/src/flycheck.rs +++ b/crates/rust-analyzer/src/flycheck.rs @@ -150,10 +150,18 @@ impl FlycheckHandle { pub(crate) enum FlycheckMessage { /// Request adding a diagnostic with fixes included to a file - AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic }, + AddDiagnostic { + id: usize, + generation: usize, + workspace_root: AbsPathBuf, + diagnostic: Diagnostic, + }, - /// Request clearing all previous diagnostics - ClearDiagnostics { id: usize }, + /// Request clearing all outdated diagnostics + ClearDiagnostics { id: usize, generation: usize }, + + /// Request clearing outdated for a specific crate + ClearCrateDiagnostics { id: usize, generation: usize, package_id: String }, /// Request check progress notification to client Progress { @@ -166,15 +174,24 @@ pub(crate) enum FlycheckMessage { impl fmt::Debug for FlycheckMessage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => f + FlycheckMessage::AddDiagnostic { id, generation, workspace_root, diagnostic } => f .debug_struct("AddDiagnostic") .field("id", id) + .field("generation", generation) .field("workspace_root", workspace_root) .field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code)) .finish(), - FlycheckMessage::ClearDiagnostics { id } => { - f.debug_struct("ClearDiagnostics").field("id", id).finish() - } + FlycheckMessage::ClearDiagnostics { id, generation } => f + .debug_struct("ClearDiagnostics") + .field("id", id) + .field("generation", generation) + .finish(), + FlycheckMessage::ClearCrateDiagnostics { id, generation, package_id: crate_name } => f + .debug_struct("ClearDiagnostics") + .field("id", id) + .field("generation", generation) + .field("crate_name", crate_name) + .finish(), FlycheckMessage::Progress { id, progress } => { f.debug_struct("Progress").field("id", id).field("progress", progress).finish() } @@ -200,6 +217,10 @@ enum StateChange { struct FlycheckActor { /// The workspace id of this flycheck instance. id: usize, + + /// Differentiator for multiple runs of the flycheck + generation: usize, + sender: Sender, config: FlycheckConfig, manifest_path: Option, @@ -215,8 +236,6 @@ struct FlycheckActor { command_handle: Option>, /// The receiver side of the channel mentioned above. command_receiver: Option>, - - status: FlycheckStatus, } #[allow(clippy::large_enum_variant)] @@ -225,13 +244,6 @@ enum Event { CheckEvent(Option), } -#[derive(PartialEq)] -enum FlycheckStatus { - Started, - DiagnosticSent, - Finished, -} - pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; impl FlycheckActor { @@ -253,7 +265,7 @@ impl FlycheckActor { manifest_path, command_handle: None, command_receiver: None, - status: FlycheckStatus::Finished, + generation: 0, } } @@ -306,13 +318,12 @@ impl FlycheckActor { self.command_handle = Some(command_handle); self.command_receiver = Some(receiver); self.report_progress(Progress::DidStart); - self.status = FlycheckStatus::Started; + self.generation += 1; } Err(error) => { self.report_progress(Progress::DidFailToRestart(format!( "Failed to run the following command: {formatted_command} error={error}" ))); - self.status = FlycheckStatus::Finished; } } } @@ -332,11 +343,11 @@ impl FlycheckActor { error ); } - if self.status == FlycheckStatus::Started { - self.send(FlycheckMessage::ClearDiagnostics { id: self.id }); - } + self.send(FlycheckMessage::ClearDiagnostics { + id: self.id, + generation: self.generation, + }); self.report_progress(Progress::DidFinish(res)); - self.status = FlycheckStatus::Finished; } Event::CheckEvent(Some(message)) => match message { CargoCheckMessage::CompilerArtifact(msg) => { @@ -345,6 +356,11 @@ impl FlycheckActor { artifact = msg.target.name, "artifact received" ); + self.send(FlycheckMessage::ClearCrateDiagnostics { + id: self.id, + generation: self.generation, + package_id: msg.package_id.repr.clone(), + }); self.report_progress(Progress::DidCheckCrate(msg.target.name)); } @@ -354,15 +370,12 @@ impl FlycheckActor { message = msg.message, "diagnostic received" ); - if self.status == FlycheckStatus::Started { - self.send(FlycheckMessage::ClearDiagnostics { id: self.id }); - } self.send(FlycheckMessage::AddDiagnostic { id: self.id, + generation: self.generation, workspace_root: self.root.clone(), diagnostic: msg, }); - self.status = FlycheckStatus::DiagnosticSent; } }, } @@ -380,7 +393,6 @@ impl FlycheckActor { command_handle.cancel(); self.command_receiver.take(); self.report_progress(Progress::DidCancel); - self.status = FlycheckStatus::Finished; } } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index a34f0a3c929a..abe3e5b98d4e 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -956,7 +956,7 @@ impl GlobalState { fn handle_flycheck_msg(&mut self, message: FlycheckMessage) { match message { - FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => { + FlycheckMessage::AddDiagnostic { id, generation, workspace_root, diagnostic } => { let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(None), @@ -968,6 +968,7 @@ impl GlobalState { match url_to_file_id(&self.vfs.read().0, &diag.url) { Ok(file_id) => self.diagnostics.add_check_diagnostic( id, + generation, file_id, diag.diagnostic, diag.fix, @@ -982,7 +983,9 @@ impl GlobalState { } } - FlycheckMessage::ClearDiagnostics { id } => self.diagnostics.clear_check(id), + FlycheckMessage::ClearDiagnostics { id, generation } => { + self.diagnostics.clear_previous_check(id, generation) + } FlycheckMessage::Progress { id, progress } => { let (state, message) = match progress { @@ -1019,6 +1022,19 @@ impl GlobalState { Some(format!("rust-analyzer/flycheck/{id}")), ); } + FlycheckMessage::ClearCrateDiagnostics { id, generation, package_id } => { + let snap = self.snapshot(); + let Ok(Some(crate_id)) = snap.analysis.crate_with_id(&package_id) else { + tracing::info!("Flycheck: could not find crate '{package_id}'"); + return; + }; + let Ok(files) = snap.analysis.files_for(crate_id) else { + return; + }; + for file in files { + self.diagnostics.clear_file_previous_check(id, generation, file); + } + } } } diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs index 889a7d10adad..084b1b105923 100644 --- a/crates/test-fixture/src/lib.rs +++ b/crates/test-fixture/src/lib.rs @@ -200,6 +200,7 @@ impl ChangeFixture { meta.edition, Some(crate_name.clone().into()), version, + None, From::from(meta.cfg.clone()), Some(From::from(meta.cfg)), meta.env, @@ -238,6 +239,7 @@ impl ChangeFixture { Edition::CURRENT, Some(CrateName::new("ra_test_fixture").unwrap().into()), None, + None, From::from(default_cfg.clone()), Some(From::from(default_cfg)), default_env, @@ -280,6 +282,7 @@ impl ChangeFixture { Edition::CURRENT, Some(CrateDisplayName::from_canonical_name("core")), None, + None, Default::default(), Default::default(), Env::from_iter([( @@ -327,6 +330,7 @@ impl ChangeFixture { Edition::CURRENT, Some(CrateDisplayName::from_canonical_name("proc_macros")), None, + None, Default::default(), Default::default(), Env::from_iter([(