rust-lang / rust-lang/rust-analyzer
VFS miss when Cargo diagnostic refers file from custom toolchain
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.9k
- Forks
- 2.2k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 72
Description
Summary
When using rust-analyzer with a custom toolchain linked using rustup toolchain link, its symbolic link is resolved in VFS but not when loading Cargo diagnostics, which causes a (potentially benign?) VFS miss. Rust-analyzer shows a File with cargo diagnostic not found in VFS: file not found error.
Reproduction
(I have not found a way yet to have rust-analyzer call Clippy on a standalone install (i.e. using rust-analyzer diagnostics) as recommended on the troubleshooting section of the manual, so for now this reproduction requires opening a code editor. In this example, I use Visual Studio Code 1.68.0 on Windows 10)
-
Create a custom toolchain and link it using
rustup toolchain link.# We use a copy of stable Rust 1.61 in this example, which we place on a folder we # create on .cargo; this is closest to the failure seen in the wild. # (The first two commands are "translations" of steps I actually did using Windows File Explorer, # since I'm more familiar with Linux commands) mkdir ~/.cargo/my_custom_toolchains cp -r ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu ~/.cargo/my_custom_toolchains/totally-custom-toolchain rustup toolchain link totally-custom-toolchain ~/.cargo/my_custom_toolchains/totally-custom-toolchain # No need to switch to newly-created "totally-custom-toolchain"; we will instead set `RUSTUP_TOOLCHAIN`. -
Create a new Cargo project, and add some code that causes Clippy to issue a diagnostic where one of the files points to our custom toolchain's standard library source. For example, some forms of
clippy::to_string_in_format_args, when diagnosed within a declarative macro, show the source file for such macro. In this case, we useprintln!, defined onstd'ssrc/macros.rs, and a bit of indirection:use std::collections::HashMap; fn main() { let mut world_map = HashMap::new(); world_map.insert(0, String::from("world")); println!("Hello, {}!", world_map.get(&0).unwrap().to_string()); } -
Configure the editor to use the custom toolchain, and enable Clippy diagnostics.
{ "rust-analyzer.checkOnSave.enable": true, "rust-analyzer.checkOnSave.command": "clippy", "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "totally-custom-toolchain" } // All other settings at their default values } -
Open the project. On the Rust Analyzer Language Server output log, the following error shows:
[ERROR rust_analyzer::main_loop] File with cargo diagnostic not found in VFS: file not found: c:\Users\USER\.rustup\toolchains\custom-toolchain-test\lib\rustlib\src\rust\library\std\src\macros.rs
Diagnosis
When building the VFS, due to https://github.com/rust-lang/rust-analyzer/pull/6246, symlinks are resolved/normalized to the canonical paths. Thus, if the Rust std is behind a symlink, e.g. when using a toolchain linked using rustup toolchain link, the VFS points to the std's source files with the symlink pre-resolved.
In the example above, the entry that is supposed to be loaded on the VFS for std's src/macros.rs is actually loaded, but as:
c:\Users\USER\.cargo\my_custom_toolchains\totally-custom-toolchain\lib\rustlib\src\rust\library\std\src\macros.rs
However, Cargo diagnostics do not resolve files this way, and thus Rust-analyzer receives instead:
c:\Users\USER\.rustup\toolchains\custom-toolchain-test\lib\rustlib\src\rust\library\std\src\macros.rs
which errors out with the aforementioned error when rust-analyzer tries to resolve the file here after the event loop receives the corresponding flycheck::Message::AddDiagnostic message: https://github.com/rust-lang/rust-analyzer/blob/604b1c8409e850e738e0c211a11de0c42171a979/crates/rust-analyzer/src/global_state.rs#L371-L372
Remarks
This bug seems to be benign in practice, since Rust-analyzer is still able to display the issue on the editor, apply quick-fixes and even provide working links to all the files, including the failed one, on both the hover card and the Problems tab of Visual Studio Code. I thus don't really see any user-facing consequences this issue may have, but since this is the first time I have worked with the Rust-Analyzer codebase I may be missing something.
System Information
rust-analyzer version: rust-analyzer version: 0.0.0 (366bd7242 2022-06-12)
rustc version:
- The reproduction above was done using
rustc 1.61.0 (fe5b13d68 2022-05-18). - The issue was originally found in the wild using the Skyline custom
stdlib(branchskyline), which reportsrustc 1.63.0-nightly (e6a4afc3a 2022-05-20).
relevant settings: the reproduction above was found on Windows 10 Pro 21H2 (10.0.19044), with the settings described on the reproduction, on a NTFS file system.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with a rustup-linked custom toolchain and Clippy diagnostics, then inspect the VFS path handling and the flycheck::Message::AddDiagnostic path at crates/rust-analyzer/src/global_state.rs#L371-L372. Trace how canonicalized VFS paths differ from Cargo diagnostic paths; done means the diagnostic file resolves without a VFS miss for the linked toolchain.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100