rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.07k stars 1.57k forks source link

Cargo diagnostics cache corruption #14681

Closed ia0 closed 1 year ago

ia0 commented 1 year ago

The checkOnSave feature of rust-analyzer corrupts the cargo diagnostics cache. See the reproduction steps in this comment: https://github.com/rust-lang/rust-analyzer/issues/14681#issuecomment-1528796226.

Original (and now irrelevant) post is kept below for context: The checkOnSave does exactly what it says: it runs the "check" command on "didSave". I'm suggesting to also add a checkOnStart (or checkOnInit) which would run the "check" command when the server starts.

Veykril commented 1 year ago

this should already be the case if checkOnSave is enabled

ia0 commented 1 year ago

Indeed, I can see flycheck running in the LSP connection logs, however I don't get publishDiagnostics notification from the server. While trying to play around and reproduce, I realized that if I first cargo clean (or manually delete the target directory) and then open src/lib.rs in emacs, then I get the publishDiagnostics notification. And if I restart I still get them. So there's some operation, that I did not identify yet, that somehow breaks this and I have to cargo clean to restore the situation. I'll try to play a bit more to see if I can pinpoint the manipulation I do that "corrupts" the target directory (or its usage by rust-analyzer). So far I played with the following operations:

ia0 commented 1 year ago

Ok, I think the feature is unrelated and the problem is related to having lib.rs and main.rs and having an error in one "mask" the error in the other (no error shown in main if lib is wrong), then removing the file masking errors in the other file, we won't get the errors in the other file back. Working on a step by step reproduction. But anyway, I don't think this is a rust-analyzer issue, I think this is a cargo issue.

ia0 commented 1 year ago

I have repro steps with rust-analyzer. And I can't reproduce using cargo check --all-targets, which means it's rust-analyzer corrupting the cargo diagnostics cache.

Setup

Create those 4 files in an empty directory:

[package]
name = "foo"
version = "0.1.0"
edition = "2021"
// src/lib.rs-ok
pub fn foo() {}
// src/lib.rs-err
pub fn foo() {
    core::mem::size_of_val();
}
// src/main.rs
fn main() {
    core::mem::size_of_val();
}

Instructions

Those are the steps to reproduce the rust-analyzer diagnostics cache corruption. The same instructions may be followed without opening src/lib.rs in an editor (thus without rust-analyzer). All cargo check --all-targets behave as expected in that case.

Populate the cache

Corrupt the cache

Exploit the cache

ia0 commented 1 year ago

I created #14722 instead to get the correct label.