-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Granular handling for flycheck diagnostics #18332
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we already have everything available to imrpove this without having to add generations and stuff,
In https://github.com/Veykril/rust-analyzer/blob/95298a2e61eb852b165faaaa2dcf1713001731ce/crates/rust-analyzer/src/flycheck.rs#L504 we drop the package_id
of the message, we can keep that as our identifier for a crate (these diagnostics work on packages not crates so).
Here https://github.com/Veykril/rust-analyzer/blob/95298a2e61eb852b165faaaa2dcf1713001731ce/crates/rust-analyzer/src/flycheck.rs#L342-L349
we already know when we are done with checking a specific package, again msg.package
contains an identiifer to identify the package with.
So we can change how flycheck works a bit, we can make it maybe collect all diagnostics first, then s end them out as one big message per package whenever we receive the corresponding CargoCheckMessage::CompilerArtifact
message for a package.
Thats a very rough description of thinsg but I think with that and a bit of fleshing out the details we can have a nicer solution (I am not a big fan of the generation stuff)
Hmm, I saw that the package id was accessible, but I'm not sure where/how to match it to an actual
Batching diagnostics around crates was an idea I also experimented with, but I'm not confident it can fully work as is. Erasing diagnostics crate by crate without a generation counter means we can't do a 'full clear' of diagnostics at any point in the process, and so it means that if a file isn't correctly included in our representation of the crate graph (if it stops being included, or maybe some |
c5ebca1
to
bf9b625
Compare
@@ -277,6 +277,7 @@ pub struct CrateData { | |||
pub root_file_id: FileId, | |||
pub edition: Edition, | |||
pub version: Option<String>, | |||
pub package_id: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CrateData is agnostic to cargo packages so we shouldn't store this here (and we shouldn't have to either way)
@@ -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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we should instead iterate the workspaces (and then the packages in those) to find the relevant crates
let Ok(files) = snap.analysis.files_for(crate_id) else { | ||
return; | ||
}; | ||
for file in files { | ||
self.diagnostics.clear_file_previous_check(id, generation, file); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With our changes, I feel like it'd be better to change how we store native diagnostics, keep them in a map HashMap<PackageId, ...>
instead of per file, then when we actually pull the diagnostics out to report them we can just iterate that and turn it into per file stuff accordingly.
Then we don't need to iterate the files of a crate which is a bit fishy (if a person removes a mod statement we lose the connection to a file and now we have stale diagnostics that wont get cleared there)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, removing the correlation with FileId
really doesn't play well with the way DiagnosticsCollection
handles accessing the diagnostics. I'm honestly having quite a bit of trouble finding a way to do that cleanly, since we need more context than just the diagnostic to get back the exact file it applies to.
I did think of the dangling files though, it's one of the reasons there's a generation index, I did make it so that we clean up everything from the previous generation at the end of a flycheck, so dangling files will be included in that last pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've implemented what I meant in (sorry for stealing your work here now): #18729
Please give that a review, maybe I misunderstood your problem and there are issues with that approach that I don't see
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, I was definitely overthinking the initial comment ! I was very hesitant of nesting yet another level of hashmap into the diagnostics, but yeah that's just cleaner that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that explains things. The nesting there is fine since we can assume not a lot of diagnostics to occur.
504d4a7
to
bf9b625
Compare
bf9b625
to
7203d51
Compare
This is my proposed solution for #18283
This implements 2 things:
This meant adding some facilities to find a crate by name and iterate over its files, which are the parts I'm the least confident about. This is my first PR for this project, so I'm ready for extensive feedback if need be :)