Skip to content

Run rust-analyzer against the stable toolchain - #3179

Closed
WesleyRosenblum wants to merge 2 commits into
mainfrom
WesleyRosenblum/rustanalyzermsrv
Closed

Run rust-analyzer against the stable toolchain#3179
WesleyRosenblum wants to merge 2 commits into
mainfrom
WesleyRosenblum/rustanalyzermsrv

Conversation

@WesleyRosenblum

@WesleyRosenblum WesleyRosenblum commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Release Summary:

Resolved issues:

N/A

Description of changes:

rust-toolchain pins this repository to its MSRV, and CI derives the MSRV from that file. rust-analyzer has since raised its minimum supported toolchain to 1.94.0 (f0d6308, released in 2026-07-27), so the language server now emits an unsupported toolchain warning on every workspace load and, more importantly, resolves std macros incorrectly.

The functional break is rust-analyzer#22784, which stopped treating the sysroot crates as #[macro_use]. std began exporting its macros explicitly from the prelude in rust-lang/rust#139493, which landed in 1.94. Against an older sysroot, rust-analyzer's model of std macro resolution no longer matches the actual stdlib, so assert!, vec!, format! and friends misresolve. This is not going to settle down on its own: a follow-up has already removed format_args lowering for pre-1.94 toolchains, and upstream policy is that only the latest stable stdlib is supported.

This adds a .vscode/settings.json that sets RUSTUP_TOOLCHAIN for the language server process only, which is the workaround documented by rust-analyzer for projects with a toolchain override. RUSTUP_TOOLCHAIN takes precedence over a rust-toolchain file, so the server gets a stable sysroot while terminal invocations of cargo build, cargo clippy, and cargo fmt continue to resolve the pinned toolchain. MSRV violations are still caught locally.

Two supporting settings come along with it. cargo.targetDir gives the server its own target directory, since it now checks with a different rustc than terminal builds use and would otherwise invalidate their fingerprints and trigger full rebuilds. --locked stops stable's cargo from rewriting a Cargo.lock that the pinned toolchain has to read.

No change to rust-toolchain, rust-version, or CI. The MSRV is unchanged.

Call-outs:

This only helps editors that read .vscode/settings.json. Contributors on Zed, Neovim, or Helix will still see the warning and need the equivalent RUSTUP_TOOLCHAIN override in their own configuration.

The editor-agnostic alternative is adding rust-analyzer to components in rust-toolchain, which makes rustup supply the version-matched server for any editor. I did not go that route because it freezes everyone on the December 2025 server, which degrades further as upstream keeps deleting pre-1.94 compatibility paths.

Editor diagnostics now come from stable. rust-analyzer's check-on-save inherits the override, so a post-MSRV stdlib API will not be flagged as you type. It still fails on the next terminal build and in the MSRV CI job. Enforcement moves from as-you-type to when-you-build, not to CI. Pinning check.overrideCommand to the MSRV toolchain would restore in-editor enforcement, but it hardcodes the version in a second place that would silently go stale on the next MSRV bump.

tools/xdp/ebpf pins nightly-2025-10-01 and needs rust-src for build-std. The override applies to the whole server process, so that crate cannot be analyzed against a stable sysroot. In practice it appears to already be unanalyzed: it is excluded from workspace discovery in ci.yml, and it is not reachable from the root workspace. Anyone who does want to work on it needs a separate window.

A longer-term option, not taken here, is to decouple the MSRV from the development toolchain: declare the MSRV explicitly in ci.yml the way RUST_NIGHTLY_TOOLCHAIN already is, or read it from the rust-version field already present in every crate's Cargo.toml, and let rust-toolchain track recent stable. That would fix this for every editor with no per-editor config, at the cost of local builds no longer catching MSRV violations at all.

Testing:

No functional change to shipped code; this only affects local editor configuration. Verified manually on macOS aarch64 with rust-analyzer extension 0.3.2989:

  • rustc --version in the repository root resolves 1.92.0, and with RUSTUP_TOOLCHAIN=stable resolves 1.97.1, confirming the override reaches the server without affecting terminal builds.
  • The stable toolchain provides both rust-src and libexec/rust-analyzer-proc-macro-srv, so no additional components are required.
  • All four settings keys validate against the extension's configuration schema.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

rust-analyzer raised its minimum supported toolchain to 1.94.0, so running
the language server against the MSRV sysroot pinned in rust-toolchain
breaks std macro resolution: the sysroot crates are no longer implicitly
`#[macro_use]`d, since std began exporting its macros explicitly from the
prelude in 1.94.

Set RUSTUP_TOOLCHAIN only for the language server process. Terminal
invocations of cargo build, clippy, and fmt still resolve the pinned
toolchain from rust-toolchain, so MSRV violations are still caught
locally. Editor analysis no longer warns and macro expansion works again.

Also give the server its own target directory, since it now checks with a
different rustc than terminal builds use and would otherwise invalidate
their fingerprints, and pass --locked so stable's cargo cannot rewrite a
Cargo.lock that the pinned toolchain has to read.

This only covers editors that read .vscode/settings.json; contributors on
other editors need the equivalent override in their own configuration.
`cargo.extraArgs` is passed to every cargo invocation, and `check.extraArgs`
extends it rather than replacing it, so flycheck was invoked with `--locked`
twice and cargo rejected the command:

    error: the argument '--locked' cannot be used multiple times

Keep it only on `cargo.extraArgs`, which covers both `cargo metadata` and
`cargo check`.
@WesleyRosenblum

Copy link
Copy Markdown
Contributor Author

Decided to go with the approach in #3180

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant