Open
Description
Few notes:
- This issue is my attempt to consolidate discussion from Zulip, A Plan for Making Rust Analyzer Faster #17491, comments, and Proper support for standalone/detached files #14318.
- The term "workspace" is often used in rust-analyzer; I'm going to use "project" because an indexed project might not have a 1:1 correspondence to a VS Code workspace. In fact, there might be multiple, indexed projects in a single workspace, or there might be no workspace at all!
Anyway! Project discovery should be entirely lazy. This change makes the following easier:
- Monorepos. Projects are often discovered incrementally as the user navigates around a monorepo and it doesn't make sense to do Cargo-style project discovery at startup.
- Standalone files, like rustlings. Users would be able to just open a Rust file, and through a
rust-analyzer.toml
in the rustlings repo, IDE functionality would just work for them. - Cargo scripts, which have a similar dynamic to that of rustlings/monorepos but scaled down from the latter.
To make this change happen, the currently eager (that is, they occur on startup/workspace folder change) ProjectManifest::discover_all
+ cargo metadata-style operations would become lazy, rust-analyzer.workspace.DiscoverCommand
-style operations that only happen after startup. This would mean several things:
- Project discovery/indexing wouldn't start until a user opens a Rust file.
cargo_metadata::MetadataCommand::new()
would become the default mode forflycheck/src/json_workspace.rs
(see this comment. That file would no longer be JSON workspace-specific, but it would also make "project discovery" a first-class concept in rust-analyzer.rust-analyzer.linkedProjects
would technically be lazily evaluated, but if any value is set, it would effectively be "eagerly" evaluated.- The current "rust-analyzer only searches two directory levels down for a Cargo.toml" behavior can be removed in favor of "run cargo-metadata in the parent of the rust file"-esque behavior, which newer Rust users often struggled with and complained about.
To support this change, I think three things need to happen:
- feature: teach rust-analyzer to discover
linked_projects
#17246 needs to land. - The crate graph should be lifted into a standalone, Salsa database.
- Salsa's interning infrastructure should be used with the crate data as the "key". This is necessary in order to support different feature flags/versions across projects.
- A nice performance bonus, the VFS should be able to load all a project's files in a single go.
- Today, rust-analyzer doesn't have a meaningful distinction between the user-facing "startup" and "steady-state, using-the-IDE" phases. It is always already to incrementaly update and rebuild the crate graph, which it does many times during project loading. I think it is worthwhile to have this distinction because it'd then be possible to load all relevant files in a single turn extremely quickly.
- This is particularly important on network-backed file systems, like EdenFS. I've observed 180x speedups through some naive usage of Rayon.