Using rust-analyzer in VSCode with Rust installed through rtx

Rust newbie here, so pardon the possibly simplistic question...

I've setup Rust using rtx (GitHub - jdxcode/rtx: Runtime Executor (asdf rust clone)) and now I'm trying to get rust-analyzer to work in VSCode. However I'm stumbling over how to get it to realize that rustup, cargo, et. al. are installed via rtx, so it fails on startup with this error:

[ERROR rust_analyzer::main_loop] FetchWorkspaceError:
rust-analyzer failed to load workspace: cd "/Users/me/dev/playground/opencv-rust" && "cargo" "--version" failed: No such file or directory (os error 2)

I believe it is unable to find the cargo command, which makes sense since it's not on the default path, being managed via rtx. rtx typically installs hooks in the shell - in my case by running eval "$(/opt/homebrew/bin/rtx activate zsh)" in my ~/.zshrc.

Running cargo --version in Code's Terminal works fine - since it runs my .zshrc first, rtx is loaded and all is well. Of course the plugin does not do that, so it fails when it tries to load.

I've tried to fix this by adding configs to override the default commands, prefixing them with rtx exec rust --, however that hasn't solved the issue. Here are the configs I added:

    "rust-analyzer.cargo.buildScripts.overrideCommand": [
        "rtx exec rust -- cargo check --quiet --workspace --message-format=json --all-targets"
    "rust-analyzer.check.overrideCommand": ["rtx exec rust -- cargo check --workspace --message-format=json --all-targets"],

Is there some way I can make this setup work, or do I have to rely on rustup for version management and abandon the rtx approach? If possible I'd like to keep rtx since I manage all of my programming language environments with it and that consistency helps my poor brain not get overloaded when trying to figure out how to switch versions for a given programming language. I have very limited brain capacity and I play with lots of different languages... ;]

I think rust-analyzer makes a pretty deep assumption that cargo is a binary (rather than a binary with argumens). You should be able to override the cargo it uses with:

    "rust-analyzer.server.extraEnv": {
        "CARGO": "/path/to/cargo",

But it seems that the core problem here is that the environment in the terminal, and in the GUI apps is different. So the best way to fix that would be to arrange for rtx to also set up env for all graphical programs. Don't know how to do that though.

1 Like

Ugh, so of course AFTER I posted this I had a brainstorm (well, probably more like a brainfart).

I added small scripts for cargo, rustup, and rustc to my ~/bin directory with this content:

rtx exec rust -- cargo $@

and removed the config overrides above and with that rust-analyzer now works in VSCode. So... yay?

This feels rather hacky though and leaves me wondering if I'm missing something a obvious/better solution here...

Oops - sorry, didn't see this before I posted my reply.

The extraEnv approach seems decent - as long as it works with the rtx exec - I'll have to try that.

However, I also need to override rustup and rustc from what I observed, so do similar settings exist for those 2 as well?

I don't think rtx can do anything about the GUI env, being a CLI itself (this is on a Mac, btw.). At least I wouldn't know how to do that, either. ;]

Yeah, so I tried setting:

    "rust-analyzer.server.extraEnv": {
        "CARGO": "rtx exec rust -- cargo",

and that resulted in this error:

[ERROR rust_analyzer::main_loop] FetchWorkspaceError:
rust-analyzer failed to load workspace: cd "/Users/me/dev/playground/opencv-rust" && "rtx exec rust -- cargo" "--version" failed: No such file or directory (os error 2)

Probably because it's looking for cargo to be a plain binary, as you correctly assumed (trying to run the executable as "rtx exec rust -- cargo", which of course doesn't exist).

Yeah, that would be the case.

I guess

could also be of help?

1 Like

Huh, now how did I miss that!? ;] I'll have to give that a shot, thanks!

Hah, that worked - thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.