Rust-src not found, and other misadventures of developing rust on NixOS

I’m trying to set up a shell.nix for rust development:

let
  # Last updated: 2/12/21
  pkgs = import (fetchTarball("https://github.com/NixOS/nixpkgs/archive/a58a0b5098f0c2a389ee70eb69422a052982d990.tar.gz")) {};

  # Rolling updates, not deterministic.
  # pkgs = import (fetchTarball("channel:nixpkgs-unstable")) {};
in pkgs.mkShell {
  buildInputs = [
    pkgs.cargo
    pkgs.rustc

    # Necessary for the openssl-sys crate:
    pkgs.openssl
    pkgs.pkg-config
  ];
}

This is great in that it gives me cargo and rustc in the path, and I can build my project, but I’m not able to use rust-analyzer in vscode:

rust-analyzer failed to load workspace: Failed to find sysroot for Cargo.toml file /home/skainswo/dev/cuddlefish/api/Cargo.toml. Is rust-src installed?: can't load standard library from sysroot /nix/store/l3icq4dzpk5cwq3mf4459cd7ydrxvy0i-rustc-1.49.0 (discovered via `rustc --print sysroot`) try installing the Rust source the same way you installed rustc

Ok, so I’m missing some kind of package called rust-src, which I’m assuming contains extra goodies. But a quick search reveals no nix packages: NixOS Search - Loading....

I did notice that nixpkgs/rust-src.nix at 8199872bba4fdb836c093b58ee4092266fec5592 · NixOS/nixpkgs · GitHub exists, although I have no idea how to “use” it. How is this exposed to users?

Also, our wiki entry on rust (Rust - NixOS Wiki) looks a bit sad atm. I’d be more than happy to update it, although I still haven’t figured out how to get things working for my own purposes yet…

Anyone know how to use rust-analyzer with the nixpkgs versions of rustc and cargo?

Update: just found the pkgs.rust.packages.stable.rustPlatform.rustcSrc package, but unfortunately adding it does not seem to change anything…

Many Rust analysis tools will inspect RUST_SRC_PATH, so you should be able to do something like (untested):

pkgs.mkShell {
   # ...

   RUST_SRC_PATH = "${rustPlatform.rustLibSrc}";
}
2 Likes

Using the rust-overlay provided by @oxalica I was able solve the issue you’re facing with the following in my shell.nix:

{}:
let
  rust-overlay = (import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"));
  pkgs = (import <nixpkgs> {
    overlays = [ rust-overlay ];
  });
in
pkgs.mkShell {
  buildInputs = [
    (pkgs.rust-bin.stable.latest.rust.override {
      extensions = ["rust-src"];
    })

    # keep this line if you use bash
    pkgs.bashInteractive
  ];
}

You can additionally pick your preferred rust channel in with this overlay as well.

2 Likes

This did the trick for me, thank you!! Out of curiosity, why doesn’t cargo or rustc set up this env var automatically? I feel like it would be convenient for users to have a single derivation they could include and get a full, working rust development environment.

EDIT: The full bit that worked for me was

RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";

for anyone that comes across this issue in the future…

1 Like

This would add the library source to the closure of cargo/rustc.

Perhaps we could include a new convenience derivation like rust-everything (or rust-moar or just-let-me-rust) or something to bring in rustc, cargo, rustLibSrc, rustfmt, etc?