linuxrustnixnixos

rust toolchain error on NixOS when installed via nix


I recently switched to NixOS and installed the Rust toolchain (rustup, cargo, rustc) using the Nix package manager.

However, when I try to open my pre-configured Neovim setup, I get the following LSP error:

Client rust-analyzer quit with exit code 1 and signal 0. Check log for errors: /home/user/.local/state/nvim/lsp.log

Looking at the lsp.log file, I see this error message: [ERROR] .../vim/lsp/rpc.lua:420 "rpc" "/run/current-system/sw/bin/rust-analyzer" "stderr" "error: Unknown binary 'rust-analyzer' in official toolchain 'stable-x86_64-unknown-linux-gnu'.\n"

At first, I thought it might be a Neovim issue related to how Nix manages packages. So, I tried running rust-analyzer directly from the terminal, but I get the same error:

$ rust-analyzer
error: Unknown binary 'rust-analyzer' in official toolchain 'stable-x86_64-unknown-linux-gnu'.

I realized that rust-analyzer might not have been installed automatically with the rustup package from Nix, so I explicitly installed rust-analyzer using the Nix package manager as well.

Despite this, the behavior remains identical for rust-analyzer.

Running which rust-analyzer correctly shows the path:

$ which rust-analyzer
/run/current-system/sw/bin/rust-analyzer

But running it directly using the absolute path still produces the same "Unknown binary" error:

$ /run/current-system/sw/bin/rust-analyzer
error: Unknown binary 'rust-analyzer' in official toolchain 'stable-x86_64-unknown-linux-gnu'.

Furthermore, I reinstalled all the Rust packages, including rustfmt and rustc, but now I am encountering similar issues with them when trying to use them (either directly in the terminal or via Neovim integrations). Specifically, I am getting errors indicating that rustfmt and rustc cannot choose a version to run because one wasn't specified explicitly, and no default is configured. I also used the which command to find the location of these binaries, and even after confirming the correct path, running them still results in the same errors.

$ rustfmt
error: rustup could not choose a version of rustfmt to run, because one wasn't specified explicitly, and no default is configured.
help: run 'rustup default stable' to download the latest stable release of Rust and set it as your default toolchain.

$ rustc
error: rustup could not choose a version of rustc to run, because one wasn't specified explicitly, and no default is configured.
help: run 'rustup default stable' to download the latest stable release of Rust and set it as your default toolchain.

This leads me to a few questions:

  1. Considering the persistent rust-analyzer "Unknown binary" error and these new errors for rustfmt/rustc, should I install these components via rustup (e.g., rustup default stable, rustup component add rust-analyzer) instead of using the Nix package manager? Doesn't installing components via rustup somewhat contradict the declarative and reproducible nature of NixOS where dependencies are preferably managed by Nix itself?

  2. Am I missing a configuration step or misunderstanding how rustup (installed via Nix) interacts with components like rust-analyzer, rustfmt, and rustc (also installed via Nix) on NixOS?


Solution

  • The Main Reason: The whole problem was happening because I was trying to use rustup (even though installed via Nix) alongside the Rust tools (rustc, cargo, rust-analyzer, rustfmt) also installed via Nix. The conclusion is: on NixOS, you generally shouldn't install rustup if you're managing your Rust toolchain directly with Nix.

    Explanation:

    Nix/NixOS already does the "job" that rustup would do on a traditional system, but in a declarative way that's integrated with the Nix package system. rustup is designed to manage different Rust versions and components in its own directory (~/.rustup), acting as a proxy for commands like rustc, cargo, etc.

    When I installed rustup via Nix, it was placed in the system path, but it still tried to act like rustup, looking for toolchains managed by itself and expecting commands like rustup default stable or rustup component add.