Add more workaround hacks for incorrect startup diagnostics

This commit is contained in:
Lukas Wirth 2025-08-07 15:24:39 +02:00
parent 8fcc577b73
commit 015b9466c7
4 changed files with 16 additions and 8 deletions

View file

@ -216,15 +216,15 @@ fn run_server() -> anyhow::Result<()> {
} = from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?; } = from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?;
// lsp-types has a typo in the `/capabilities/workspace/diagnostics` field, its typoed as `diagnostic` // lsp-types has a typo in the `/capabilities/workspace/diagnostics` field, its typoed as `diagnostic`
if let Some(val) = initialize_params.pointer("/capabilities/workspace/diagnostics") { if let Some(val) = initialize_params.pointer("/capabilities/workspace/diagnostics")
if let Ok(diag_caps) = from_json::<lsp_types::DiagnosticWorkspaceClientCapabilities>( && let Ok(diag_caps) = from_json::<lsp_types::DiagnosticWorkspaceClientCapabilities>(
"DiagnosticWorkspaceClientCapabilities", "DiagnosticWorkspaceClientCapabilities",
val, val,
) { )
{
tracing::info!("Patching lsp-types workspace diagnostics capabilities: {diag_caps:#?}"); tracing::info!("Patching lsp-types workspace diagnostics capabilities: {diag_caps:#?}");
capabilities.workspace.get_or_insert_default().diagnostic.get_or_insert(diag_caps); capabilities.workspace.get_or_insert_default().diagnostic.get_or_insert(diag_caps);
} }
}
let root_path = match root_uri let root_path = match root_uri
.and_then(|it| it.to_file_path().ok()) .and_then(|it| it.to_file_path().ok())

View file

@ -183,6 +183,10 @@ pub(crate) struct GlobalState {
/// this queue should run only *after* [`GlobalState::process_changes`] has /// this queue should run only *after* [`GlobalState::process_changes`] has
/// been called. /// been called.
pub(crate) deferred_task_queue: TaskQueue, pub(crate) deferred_task_queue: TaskQueue,
/// HACK: Workaround for https://github.com/rust-lang/rust-analyzer/issues/19709
/// This is marked true if we failed to load a crate root file at crate graph creation,
/// which will usually end up causing a bunch of incorrect diagnostics on startup.
pub(crate) incomplete_crate_graph: bool,
} }
/// An immutable snapshot of the world's state at a point in time. /// An immutable snapshot of the world's state at a point in time.
@ -298,6 +302,7 @@ impl GlobalState {
discover_workspace_queue: OpQueue::default(), discover_workspace_queue: OpQueue::default(),
deferred_task_queue: task_queue, deferred_task_queue: task_queue,
incomplete_crate_graph: false,
}; };
// Apply any required database inputs from the config. // Apply any required database inputs from the config.
this.update_configuration(config); this.update_configuration(config);

View file

@ -141,7 +141,7 @@ impl RequestDispatcher<'_> {
Result: Serialize, Result: Serialize,
> + 'static, > + 'static,
{ {
if !self.global_state.vfs_done { if !self.global_state.vfs_done || self.global_state.incomplete_crate_graph {
if let Some(lsp_server::Request { id, .. }) = if let Some(lsp_server::Request { id, .. }) =
self.req.take_if(|it| it.method == R::METHOD) self.req.take_if(|it| it.method == R::METHOD)
{ {

View file

@ -741,13 +741,16 @@ impl GlobalState {
}) })
.collect(); .collect();
self.incomplete_crate_graph = false;
let (crate_graph, proc_macro_paths) = { let (crate_graph, proc_macro_paths) = {
// Create crate graph from all the workspaces // Create crate graph from all the workspaces
let vfs = &self.vfs.read().0; let vfs = &self.vfs.read().0;
let load = |path: &AbsPath| { let load = |path: &AbsPath| {
let vfs_path = vfs::VfsPath::from(path.to_path_buf()); let vfs_path = vfs::VfsPath::from(path.to_path_buf());
self.crate_graph_file_dependencies.insert(vfs_path.clone()); self.crate_graph_file_dependencies.insert(vfs_path.clone());
vfs.file_id(&vfs_path).and_then(|(file_id, excluded)| { let file_id = vfs.file_id(&vfs_path);
self.incomplete_crate_graph |= file_id.is_none();
file_id.and_then(|(file_id, excluded)| {
(excluded == vfs::FileExcluded::No).then_some(file_id) (excluded == vfs::FileExcluded::No).then_some(file_id)
}) })
}; };