rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

"unresolved extern crate" when importing rustc crates from a locally built toolchain

Open RalfJung opened this issue 3 years ago • 2 comments

To reproduce, first locally build a rustc (./x.py build compiler --stage 2), then check out Miri, configure it for RA as shown below, and open it in vscode. Now open the src/lib.rs file. There are errors for extern crate rustc_middle; and all the other rustc crate imports: "unresolved extern crate".

A ./miri check works fine, so the crates do exist, but RA somehow fails to find them.

rust-analyzer version: rust-analyzer version: 0.3.1148-standalone (2b472f668 2022-07-31)

rustc version: locally built rustc master

relevant settings:

// Place your settings in this file to overwrite default and user settings.
{
    "rust-analyzer.rustc.source": "discover",
    "rust-analyzer.linkedProjects": [
        "./Cargo.toml",
        "./cargo-miri/Cargo.toml"
    ],
    "rust-analyzer.checkOnSave.overrideCommand": [
        "./miri",
        "check",
        "--message-format=json"
    ],
    "rust-analyzer.buildScripts.overrideCommand": [
        "./miri",
        "check",
        "--message-format=json",
    ],
    "rust-analyzer.rustfmt.extraArgs": [
        "+nightly"
    ],
}

RalfJung avatar Aug 02 '22 01:08 RalfJung

"rust-analyzer.rustc.source": "discover" doesn't work for linked toolchains as the rust-src component is absent. You need to manually point it to the root Cargo.toml of your rust checkout.

bjorn3 avatar Aug 02 '22 07:08 bjorn3

I switch between linked toolchains and downloaded toolchains all the time, so that is not a solution.

Why can't RA auto-discover linked toolchains? Miri for example auto-discovers the rust-src location for both linked and installed toolchains just fine.

RalfJung avatar Aug 02 '22 12:08 RalfJung

I have the same issue.

Yvan-xy avatar Oct 17 '22 09:10 Yvan-xy

I'm not sure how this all works, so I'm just gonna lay out what r-a does right now for discovering. First it checks if RUST_SRC_PATH is set, and uses that if it is. Otherwise r-a invokes rustc --print sysroot with the containing directory of the workspace toml as the working directory, then checks whether {sysroot}/lib/rustlib/src/rust/library exists to use that as the path. What is miri doing differently here, what should we maybe do differently here?

Veykril avatar Oct 17 '22 09:10 Veykril

Yeah {sysroot}/lib/rustlib/src/rust/library works for normal toolchains but not for linked toolchains. I can't find where Miri even has that logic, but for a linked sysroot, the folder is $(rustc --print sysroot)/../../../library.

RalfJung avatar Oct 19 '22 19:10 RalfJung

Oh, Miri doesn't have that logic any more since $(rustc --print sysroot)/lib/rustlib/src is a symlink so these things work even without doing something special on the Miri side.

Could R-A be confused by the symlink?

RalfJung avatar Oct 19 '22 19:10 RalfJung

Ah wait, the rustc that is being invoked there is not the installed toolchain one right? (well in your case miri but whatever). I imagine that might be the problem then? I'll add some logging for the sysroot stuff that way you should be able to tell what might be going on here (I don't feel like building rustc myself tbh)

Edit: Actually setting RA_LOG=project_model::sysroot=debug should already log the commands that are invoked at least, maybe that shows some helpful info?

Veykril avatar Oct 19 '22 19:10 Veykril

The override in the Miri folder is set to the linked toolchain. So rustc --print sysroot in the Miri folder should print the right folder.

The rustc build will take a bit before I can provide logs.

RalfJung avatar Oct 19 '22 19:10 RalfJung

How is the override specified? It might not work for r-a here depending on how you set the override and where

Edit: Looks like a directory override if I see this right? That should work fine then hmm fwiw this is how we fetch the executable path for rustc and the like https://github.com/rust-lang/rust-analyzer/blob/339257397d691dda250348d5c89c761ee740a5dc/crates/toolchain/src/lib.rs#L28-L56

Veykril avatar Oct 19 '22 19:10 Veykril

How is the override specified? It might not work for r-a here depending on how you set the override and where

rustup override set

RalfJung avatar Oct 19 '22 19:10 RalfJung

Added some logging to emit the sysroot and rustc paths being used https://github.com/rust-lang/rust-analyzer/pull/13441

Veykril avatar Oct 19 '22 20:10 Veykril

The RA_LOG you suggested prints this several times

[DEBUG project_model::sysroot] Discovering sysroot for /home/r/src/rust/miri
[DEBUG project_model::sysroot] Discovering sysroot by "rustc" "--print" "sysroot"
[DEBUG project_model::sysroot] Checking sysroot: /home/r/src/rust/rustc/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library
[DEBUG project_model::sysroot] Discovering rustc source for /home/r/src/rust/miri/./Cargo.toml
[DEBUG project_model::sysroot] Discovering sysroot by "rustc" "--print" "sysroot"
[DEBUG project_model::sysroot] Checking for rustc source code: /home/r/src/rust/rustc/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml
[DEBUG project_model::sysroot] Discovering sysroot for /home/r/src/rust/miri/./cargo-miri
[DEBUG project_model::sysroot] Discovering sysroot by "rustc" "--print" "sysroot"
[DEBUG project_model::sysroot] Checking sysroot: /home/r/src/rust/rustc/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library
[DEBUG project_model::sysroot] Discovering rustc source for /home/r/src/rust/miri/./cargo-miri/Cargo.toml
[DEBUG project_model::sysroot] Discovering sysroot by "rustc" "--print" "sysroot"
[DEBUG project_model::sysroot] Checking for rustc source code: /home/r/src/rust/rustc/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml

Some of the paths it mentions indeed exist (/home/r/src/rust/rustc/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library) but others do not (/home/r/src/rust/rustc/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml).

RalfJung avatar Oct 19 '22 21:10 RalfJung

So looks like we have to extend whatever code sets up the symlink in lib/rustlib/src/rust to also set up the same symlink at lib/rustlib/rustc-src/rust?

RalfJung avatar Oct 19 '22 21:10 RalfJung

Ye I would guess so? This is what r-a is doing fwiw https://github.com/rust-lang/rust-analyzer/blob/82ac6f7d4835c5cc27b5be92fee00200dbba43bb/crates/project-model/src/sysroot.rs#L219-L238

Just simply append the path to the sysroot, and I don't think there is much more we can do from our side? Though it's odd, how does rust do this then ...

Veykril avatar Oct 19 '22 21:10 Veykril

Indeed I can confirm that https://github.com/rust-lang/rust/pull/103347 fixes this problem. :)

RalfJung avatar Oct 21 '22 13:10 RalfJung