Skip to content

Commit a24b264

Browse files
committed
Windows: Opt-out of new PATH behaviour
`RUSTUP_WINDOWS_PATH_ADD_BIN` can be used to control if and how the bin directory is added to `PATH`: 0 => don't add to path 1 => prepend to PATH unset, or anything else => append to PATH
1 parent 851e856 commit a24b264

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

src/toolchain.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -228,35 +228,48 @@ impl<'a> Toolchain<'a> {
228228
path_entries.push(cargo_home.join("bin"));
229229
}
230230

231-
// Historically rustup included the bin directory in PATH to
232-
// work around some bugs (see
233-
// https://github.com/rust-lang/rustup/pull/3178 for more
234-
// information). This shouldn't be needed anymore, and it causes
231+
// On Windows, we append the "bin" directory to PATH by default.
232+
// Windows loads DLLs from PATH and the "bin" directory contains DLLs
233+
// that proc macros and other tools not in the sysroot use.
234+
// It's appended rather than prepended so that the exe files in "bin"
235+
// do not take precedence over anything else in PATH.
236+
//
237+
// Historically rustup prepended the bin directory in PATH but doing so causes
235238
// problems because calling tools recursively (like `cargo
236239
// +nightly metadata` from within a cargo subcommand). The
237240
// recursive call won't work because it is not executing the
238241
// proxy, so the `+` toolchain override doesn't work.
242+
// See: https://github.com/rust-lang/rustup/pull/3178
239243
//
240-
// The RUSTUP_WINDOWS_PATH_ADD_BIN env var was added to opt-in to
241-
// testing the fix. The default is now off, but this is left here
242-
// just in case there are problems. Consider removing in the
243-
// future if it doesn't seem necessary.
244-
#[cfg(target_os = "windows")]
245-
if self
246-
.cfg
247-
.process
248-
.var_os("RUSTUP_WINDOWS_PATH_ADD_BIN")
249-
.is_some_and(|s| s == "1")
250-
{
251-
path_entries.push(self.path.join("bin"));
252-
}
253-
254-
// On Windows, we append the "bin" directory to PATH.
255-
// Windows loads DLLs from PATH and the "bin" directory contains DLLs
256-
// that proc macros and other tools not in the sysroot use.
257-
// It's appended rather than prepended so that the exe files in "bin"
258-
// do not take precedence over anything else in PATH.
259-
let append = cfg!(target_os = "windows").then_some(self.path.join("bin"));
244+
// This behaviour was then changed to not add the bin directory at all.
245+
// But this caused another set of problems due to the sysroot DLLs
246+
// not being found by the loader, e.g. for proc macros.
247+
// See: https://github.com/rust-lang/rustup/issues/3825
248+
//
249+
// Which is how we arrived at the current default described above.
250+
//
251+
// The `RUSTUP_WINDOWS_PATH_ADD_BIN` environment variable allows
252+
// users to opt-in to one of the old behaviours in case the new
253+
// default causes any new issues.
254+
//
255+
// FIXME: The `RUSTUP_WINDOWS_PATH_ADD_BIN` environment variable can
256+
// be removed once we're confident that the default behaviour works.
257+
let append = if cfg!(target_os = "windows") {
258+
let add_bin = self.cfg.process.var("RUSTUP_WINDOWS_PATH_ADD_BIN");
259+
match add_bin.as_deref().unwrap_or("2") {
260+
// Don't add to PATH at all
261+
"0" => None,
262+
// Prepend to PATH
263+
"1" => {
264+
path_entries.push(self.path.join("bin"));
265+
None
266+
}
267+
// Append to PATH (the default)
268+
_ => Some(self.path.join("bin")),
269+
}
270+
} else {
271+
None
272+
};
260273

261274
env_var::insert_path("PATH", path_entries, append, cmd, self.cfg.process);
262275
}

0 commit comments

Comments
 (0)