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 use println!, defined on std's src/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 #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:
|
pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> Result<FileId> { |
|
let path = from_proto::vfs_path(url)?; |
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 (branch skyline), which reports rustc 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.
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 aFile with cargo diagnostic not found in VFS: file not founderror.Reproduction
(I have not found a way yet to have
rust-analyzercall Clippy on a standalone install (i.e. usingrust-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.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:Configure the editor to use the custom toolchain, and enable Clippy diagnostics.
Open the project. On the Rust Analyzer Language Server output log, the following error shows:
Diagnosis
When building the VFS, due to #6246, symlinks are resolved/normalized to the canonical paths. Thus, if the Rust
stdis behind a symlink, e.g. when using a toolchain linked usingrustup toolchain link, the VFS points to thestd'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'ssrc/macros.rsis actually loaded, but as:However, Cargo diagnostics do not resolve files this way, and thus Rust-analyzer receives instead:
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::AddDiagnosticmessage:rust-analyzer/crates/rust-analyzer/src/global_state.rs
Lines 371 to 372 in 604b1c8
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:
rustc 1.61.0 (fe5b13d68 2022-05-18).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.