Help test Windows behavior between rustup and cargo

We're looking for help with testing a fix with how rustup behaves on Windows (especially if you do development of miri, clippy, or use rustc as a library). If you are on Windows, you can help by setting the environment variable RUSTUP_WINDOWS_PATH_ADD_BIN to 0. There are a variety of ways to set an environment variable in Windows, but the easiest is probably to just search for "environment variable" in the start menu, Settings, or the Control Panel, and then click "Environment Variables..." and add it as a user variable. You will then need to restart your terminal, editor, or IDE to pick up the change.

If you experience any problems that seem to be introduced by this (such as cargo commands not behaving with toolchains correctly), please file an issue.

What does this change do?

Historically, rustup has modified the PATH environment variable on Windows when it runs cargo or other tools so that the toolchain's "sysroot" bin directory is added to the PATH (for example, C:\Users\eric\.rustup\toolchains\stable-x86_64-pc-windows-msvc\bin). This means that when a command like cargo needed to execute rustc, or recursively execute cargo like in a third-party subcommand, it would come directly from the toolchain's bin directory instead of using the rustup proxy (which is located in your cargo home, such as C:\Users\eric\.cargo\bin).

Setting RUSTUP_WINDOWS_PATH_ADD_BIN=0 will change rustup to avoid changing the PATH variable so that cargo subcommands will execute the rustup proxies instead of directly from the toolchain directory.

Modifying PATH was originally done for various reasons that are complicated and not really relevant anymore. However, out of an abundance of caution, we are asking people to test the change before we enable it by default for everyone just in case there are any issues that we have not foreseen. For example, there might be some subtle issues with loading the rustc or std DLLs.

This change was also delayed because previously it would cause cargo to run rustc through the rustup wrapper, which would have incurred a significant overhead. That has been resolved as of Rust 1.71 (via cargo#11917) which changed cargo to avoid the wrapper automatically.

This change does not affect any other platforms because they already do not modify PATH. Setting RUSTUP_WINDOWS_PATH_ADD_BIN will have no effect on non-Windows platforms.

What does this fix?

Because rustup is placing the toolchain bin directory in PATH, that was preventing recursive calls to commands like cargo from to specifying or changing the current rustup toolchain. For example, if the subsequent commands do something like running cargo +nightly metadata, it would get an error like no such command: +nightly because it was trying to execute cargo directly instead of via the rustup proxy. Similarly setting the RUSTUP_TOOLCHAIN environment variable would also not work.

The following are examples that would fail if they try to run cargo or rustc with a different toolchain (like with the + shorthand or with the RUSTUP_TOOLCHAIN environment variable):

We appreciate your help, as we hope to switch the default in an upcoming release of rustup.

2 Likes

I ran into this just a few days ago, causing code in my xtask that worked locally to fail on Windows CI. I appreciate hearing that this platform-specific behavior is being removed.

1 Like

I've turned this on locally and haven't seen any issues yet (smoke tested most the tools/scripts I use semiregularly). I also utilize all the path remapping environment variables[1], so I'm no stranger to hastily written scripts breaking[2].

Aside: I've generally recommended scripts/tools potentially running under rustup/cargo to use ${CARGO:-cargo} for "current toolchain" cargo and rustup run toolchain cargo for specific toolchain, and to avoid using the +toolchain shorthand. (Infact I recall asking cargo to add diagnostics for receiving a +toolchain argument specifically due to hitting this.) Once this change lands by default, is there any reason to not just always use cargo?


  1. $CARGO_HOME=D:\.rust\cargo, $RUSTUP_HOME=D:\.rust\rustup, $CARGO_TARGET_DIR=D:\.rust\target; utilizing a dev drive for D:\ makes a felt improvement for anything that touches a large number of small files, e.g. updating the rust-docs and rust-src rustup components. ↩︎

  2. I've only very rarely had troubles with $CARGO_HOME, but forgetting to check $CARGO_TARGET_DIR and just using $CARGO_WORKSPACE_DIR/target isn't that uncommon. ↩︎

I think just cargo for the "current" or cargo +toolchain for an override should be fine after this change. (Though it might take a while for this change to land.)

Build scripts probably should still use $CARGO.

The current behavior causes `cargo clif build` does not work on Windows · Issue #1447 · rust-lang/rustc_codegen_cranelift · GitHub Setting the mentioned env var fixes it.