Skip to content

Add more workaround hacks for incorrect startup diagnostics #20402

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion crates/rust-analyzer/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,24 @@
tracing::info!("InitializeParams: {}", initialize_params);
let lsp_types::InitializeParams {
root_uri,
capabilities,
mut capabilities,
workspace_folders,
initialization_options,
client_info,
..
} = from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?;

// 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") {

Check failure on line 219 in crates/rust-analyzer/src/bin/main.rs

View workflow job for this annotation

GitHub Actions / Rust (macos-latest)

this `if` statement can be collapsed
if let Ok(diag_caps) = from_json::<lsp_types::DiagnosticWorkspaceClientCapabilities>(
"DiagnosticWorkspaceClientCapabilities",
val,
) {
tracing::info!("Patching lsp-types workspace diagnostics capabilities: {diag_caps:#?}");
capabilities.workspace.get_or_insert_default().diagnostic.get_or_insert(diag_caps);
}
}

let root_path = match root_uri
.and_then(|it| it.to_file_path().ok())
.map(patch_path_prefix)
Expand Down
5 changes: 5 additions & 0 deletions crates/rust-analyzer/src/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ pub(crate) struct GlobalState {
/// this queue should run only *after* [`GlobalState::process_changes`] has
/// been called.
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.
Expand Down Expand Up @@ -298,6 +302,7 @@ impl GlobalState {
discover_workspace_queue: OpQueue::default(),

deferred_task_queue: task_queue,
incomplete_crate_graph: false,
};
// Apply any required database inputs from the config.
this.update_configuration(config);
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-analyzer/src/handlers/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl RequestDispatcher<'_> {
Result: Serialize,
> + '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, .. }) =
self.req.take_if(|it| it.method == R::METHOD)
{
Expand Down
5 changes: 4 additions & 1 deletion crates/rust-analyzer/src/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,13 +739,16 @@ impl GlobalState {
})
.collect();

self.incomplete_crate_graph = false;
let (crate_graph, proc_macro_paths) = {
// Create crate graph from all the workspaces
let vfs = &self.vfs.read().0;
let load = |path: &AbsPath| {
let vfs_path = vfs::VfsPath::from(path.to_path_buf());
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)
})
};
Expand Down
Loading