So I'm currently working on making the cargo check code provide OUT_DIR for packages that run a build script, and the actual interfacing with cargo is easy. I'm not sure about how to hook it up to the rest of rust-analyzer however.
I currently have a cargo package id (e.g.
gl 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)) and an OUT_DIR path, but I'm not quite sure how to access and update the corresponding crate from
main_loop.rs. If anybody with more experience in how the crate graph is stored inside a
WorldState could point me in the right direction it would be appreciated.
Secondly I'd also love some input on how/when to schedule getting the OUT_DIR values. As we all know by know, cargo check isn't always that fast, so running it asynchronously is a must. I'm not quite sure when to launch it to get the OUT_DIR values however. Ideally we'd have a way to ask cargo for just the OUT_DIRs without having to check the entire world, but that's not the situation currently.
@Emil Lauridsen , this may not be very related, but I noticed a suspicions thing in
rls code. They depend on cargo as a package. I am not sure how this works, maybe this could mean they can access
out-dir api in their code (though I don't see any code doing exactly that)?
WorldState contains an
AnalysisHost. I think you should be able to create an
set_crate_graph on that and then
apply_change on the analysis host.
@Christopher Durham have some idea what the steps of the general cache process should be,you may be interested.
Keep in mind when I wrote that I was under the impression that a new
cargo check wouldn't re-emit the build-script-executed message. I may be wrong there, and that should simplify the process.
And there is a vscode api ExtensionContext which provide some cache related directory api , which might be usefull too.
Check seems to always replay the build-script-executed events, so we luckily shouldn't need to worry about that
@matklad It looks to me like we have no way to identify a crate in the CrateGraph by the id/name we get from cargo, is that right? If so, how would you prefer going about storing such a mapping so that we can actually set OUT_DIR without blocking on the first cargo check?
When we lower
cargo metadata to crate graph, we can remmeber a mapping from package name/target name to CrateId
Okay I've almost got it working, just gotta figure out how the get/create a ExternSourceId for a path on the fly. This would all be a lot easier if OUT_DIR was available form
cargo metadata, it's turning out a bit more dirty than I'd like, so looking forward to some feedback once I get the last bit going.
The cargo issue for that is not very encouraging
@Emil Lauridsen Currently
ExternSourceId is just a re-wrapper of
SourceRooId, such that :
let extern_source_id = ExternSoruceId(source_root_id.0);
Form the code in
world.rs ~L130 it seems to be a wrapped VfsRoot id, but that appears to use the same ids so I think I got it figured out
I created a draft PR with my current work: https://github.com/rust-analyzer/rust-analyzer/pull/3582
rust-analyzer.cargoFeatures.loadOutDirsFromCheck disabled by default? Can we enable it in the future?
It slows down initial load a lot
Oh, right. Maybe we can turn it on when we support changing workspace contents dynamically?
And I assume that's only on the first load
Would could do it lazily, the main blocker is how annoying (if even possible) adding a new VFS root and source roots on the fly. With that in place at some point, we could just run the initial
cargo check in a thread like we run
cargo check on save, and update the
OUT_DIRs on the fly.