Skip to content

Conversation

smoelius
Copy link
Contributor

@smoelius smoelius commented Oct 18, 2025

This PR implements the cargo changes for #11036. The rustup changes were implemented in rust-lang/rustup#4518.

The PR is currently organized as four commits:

  • The first expands the rustup tests to set RUSTUP_TOOLCHAIN_SOURCE. This change is not strictly necessary, but it improves the rustup tests' fidelity.
  • The second moves the pkg function to a location where the next commit can use it.
  • The third implements a test to check the fourth commit's fix.
  • The fourth warns when cargo install is invoked with a non-default toolchain, as indicated by RUSTUP_TOOLCHAIN_SOURCE.

In the third commit, two significant changes were made to simulated_rustup_environment:

  • Previously, the constructed proxy would call an always-panicking executable whenever it was asked to run cargo. Now, the proxy can be made to run the cargo under test.
  • The proxy can now be made to set additional environment variables (e.g., RUSTUP_TOOLCHAIN_SOURCE) before calling the proxied tool.

The PR is currently marked as draft because rust-lang/rustup#4518 has not yet been released. Technically, this PR could be merged before then. But testing it with a fixed rustup would seem to make sense.

Nits are welcome.

cc: @epage

@rustbot rustbot added Command-install S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 18, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 18, 2025

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@smoelius smoelius marked this pull request as draft October 18, 2025 09:36
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 18, 2025
@smoelius smoelius force-pushed the second-half-of-11036 branch from 2157847 to 9006944 Compare October 18, 2025 09:52
Copy link
Member

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDIT: The force push was to make Clippy happy.

Feel free to force-push and re-organize your commits during the iterations.

.unwrap_or_default();
self.gctx.shell().warn(format!(
"\
using non-default toolchain{maybe_toolchain} overridden by {source}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we now prefer annotate-snippets style diagnostics. See the linked pull requests in #15944 for references.

(I guess the "use cargo +stable install …" can be rendered under a help:)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using warn is fine if its a single message but yes, this should be two messages as written, a warn and help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please tell me if I used the new API incorrectly.


/// Performs a `cargo install` with a non-default toolchain in a simulated
/// rustup environment. The purpose is to verify the warning that is emitted.
#[cargo_test]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prefer tests for a behavior change on its own commit first, so that in the next fix impl commit we can see the behavior change through test assertion/snapshot diff.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that with what was said, each commit should pass tests. As the last commit has no test changes, I'm assuming that instead you added all tests as if feature is implemented and put them in the test commit.

See https://doc.crates.io/contrib/process/working-on-cargo.html#submitting-a-pull-request for more details

use cargo_test_support::install::{assert_has_installed_exe, assert_has_not_installed_exe, exe};
use cargo_test_support::paths;

fn pkg(name: &str, vers: &str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For myself, I'm not too much of a fan of us reusing like this as it hides in the test what is happening and gets annoying when you just need a little customization. Just directly publish the needed package inside of your test.

[DOWNLOADING] crates ...
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
[INSTALLING] foo v0.0.1
[WARNING] using non-default toolchain `test-toolchain` overridden by env
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the new rustup is released, to avoid it causing annoyances in our tests, I suspect we want to update

fn test_env(mut self) -> Self {
to loop through RUSTUP_* and env_remove them from the binary being executed

// The toolchain rustc needs to call the real rustc. In order to do that,
// it needs to restore or clear the RUSTUP environment variables so that
// if rustup is installed, it will call the correct rustc.
let rustup_toolchain_source_setup = match std::env::var_os("RUSTUP_TOOLCHAIN_SOURCE") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should be doing anything based on the rustup we are running in

See also #16131 (comment)

Comment on lines +104 to +109
/// Arguments
///
/// - `proxy_calls_cargo`: if true, the cargo proxy calls the cargo under test;
/// otherwise, the cargo proxy calls an executable that panics immediately
/// - `env_setup`: environment variable setup the proxy should perform
fn simulated_rustup_environment(proxy_calls_cargo: bool, env_setup: &str) -> RustupEnvironment {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These make the tests much harder to read and not thrilled about injecting code directly into things.

/// Performs a `cargo install` with a non-default toolchain in a simulated
/// rustup environment. The purpose is to verify the warning that is emitted.
#[cargo_test]
fn cargo_install_with_non_default_toolchain() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should likely have cargo install tests for

  • Rustup that doesn't set RUSTUP_TOOLCHAIN_SOURCE
  • For each value of RUSTUP_TOOLCHAIN_SOURCE
  • For an unknown value of RUSTUP_TOOLCHAIN_SOURCE (handling future cases where new values are added)

Comment on lines +341 to +343
&& !matches!(
source,
RustupToolchainSource::Default | RustupToolchainSource::CommandLine
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downside to matches! is we can miss it if new values are added. For now, that is not likely to happen as this is all for one feature. That might not always be the case.

I would

  • Move the &str -> RustupToolchainSource to a function on get_rustup_toolchain_source (shouldn't touch gctx)
  • Have a function on RustupToolchainSource that lts is ask the question we are asking here and uses a match with every case enumerated

.map(|toolchain| format!(" `{toolchain}`"))
.unwrap_or_default();
let report = &[Level::WARNING
.primary_title(format!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too obvious but we are limiting ourselves to secondary_titles for now

"using non-default toolchain{maybe_toolchain} overridden by {source}"
))
.element(Level::HELP.message(format!(
"Use `cargo +stable install` if you meant to use the stable toolchain."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change Use to use. Our messages should be lower case

I really wish we had [+default](#t-rustup > Could we support `+default` toolchain? @ 💬) to suggest here.

If its purely for diagnostic purposes, we could run rustup show active-toolchain, parse the output, and show that toolchain here. If we ever want to force its use, it needs to be a more strictly defined programmatic interface.


fn get_rustup_toolchain_source(&self) -> Option<RustupToolchainSource> {
self.gctx
.get_env("RUSTUP_TOOLCHAIN_SOURCE")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My gut reaction is we should make an exception and read from std::env. That seems matched with

// ALLOWED: `RUSTUP_HOME` should only be read from process env, otherwise
// other tools may point to executables from incompatible distributions.
#[allow(clippy::disallowed_methods)]
std::env::var_os("RUSTUP_HOME").is_some()

but then we have this

gctx.get_env("RUSTUP_HOME"),
gctx.get_env("RUSTUP_TOOLCHAIN"),

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants