Skip to content

VFS miss when Cargo diagnostic refers file from custom toolchain #12534

Description

@Nnubes256

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)

  1. 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`.
  2. 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());
    }
  3. 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
    }
  4. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-flycheckissues with flycheck a.k.a. "check on save"C-bugCategory: bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions