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.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think I follow what you're asking for.

Could you give me some pseudo-code? Or could you point to a function that uses this pattern?

Copy link
Contributor

Choose a reason for hiding this comment

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

Move the &str -> RustupToolchainSource to a function on get_rustup_toolchain_source (shouldn't touch gctx)

That has happened

Have a function on RustupToolchainSource that lts is ask the question we are asking here and uses a match with every case enumerated

impl RustupToolchainSource {
    fn is_current_dir_override(&self) -> bool {
        match self {
        }
    }
}

(name is not prescriptive, just the first thing I could think of for what might describe what we care about)

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 this is still not resolved. My request is to use an exhaustive match for where we determine the policy for when we care and suggested that can be split out into a function.

The current state of the PR is is_<variant> methods are added and are being used like the match! that was here before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My request is to use an exhaustive match for where we determine the policy for when we care and suggested that can be split out into a function.

Are you asking for something like this?

impl RustupToolchainSource {
    fn is_current_dir_override(&self) -> bool {
        match self {
            Self::Default => false,
            Self::Environment => true,
            Self::CommandLine => false,
            Self::OverrideDB => true,
            Self::ToolchainFile => true,
            Self::Other(other) => true,
        }
    }
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, though Self::Other is new since my original framing. The question is what should we do in that case. My guess is the decision should be owned by the caller of this function, so returning Option<bool> and we should likely skip warning the user to avoid false positives. Maybe we could log a message in the Other case.

@rustbot

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. label Nov 6, 2025
@smoelius smoelius force-pushed the second-half-of-11036 branch from c64e01a to f0f222f Compare November 6, 2025 23:07
@smoelius
Copy link
Contributor Author

smoelius commented Nov 6, 2025

Just FYI, I know it looks like only some of the comments have been addressed. I am still hoping to get feedback on #16131 (comment) and #16131 (comment).

@rustbot rustbot added A-infrastructure Area: infrastructure around the cargo repo, ci, releases, etc. A-testing-cargo-itself Area: cargo's tests labels Dec 28, 2025
@smoelius smoelius force-pushed the second-half-of-11036 branch from f75ccb8 to a386ddd Compare December 28, 2025 21:21
@smoelius
Copy link
Contributor Author

smoelius commented Dec 28, 2025

I resolved comments that I thought I implemented uncontroversially. I hope that was okay.

EDIT: I also hid a few of my own comments that were old.

@epage
Copy link
Contributor

epage commented Dec 30, 2025

Please clean up your commits for how they should be reviewed and merged, rather than for how it was developed.

Copy link
Member

Choose a reason for hiding this comment

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

nit: Can we have some explanation in the commit message, so the commit standalone tells why we need this? It is hard to tell whether this is a refactor or a bugfix for the testsuite.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you asking for one comment per commit? Or one comment describing the entire PR in one of the commits? Either way, I am happy to oblige.

Copy link
Member

Choose a reason for hiding this comment

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

I reviewed the code commit by commit, so was specifically asking the first commit. Not a blocker though. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a comment describing the PR to the first commit. Please tell me if it is unclear or insufficient.

cargo_install_with_toolchain_source(Some("invalid"), false);
}

fn cargo_install_with_toolchain_source(source: Option<&str>, should_warn: bool) {
Copy link
Member

Choose a reason for hiding this comment

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

Instead of passing boolean we can make the argument impl snapbox::IntoData so that every test has its own snapshot. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What would the impl snapbox::IntoData be? Could you give me an example?

Copy link
Contributor

Choose a reason for hiding this comment

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

He's asking to pass in stderr rather than creating it within the test

Copy link
Contributor

Choose a reason for hiding this comment

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

For more context:

  • it makes the test easier to evaluate what it does
  • we prefer using snapshots (str![]), rather than hard coded values, wherever possible so we can easily update all tests when unrelated formatting changes

Copy link
Contributor

@epage epage Jan 2, 2026

Choose a reason for hiding this comment

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

Looks like this is still outstanding

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could easily change cargo_install_with_toolchain_source's second argument from &str to impl snapbox::IntoData. But I sense that more is needed?

Copy link
Contributor

Choose a reason for hiding this comment

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

The signature should be changed to that and a str![] should be passed in, rather than calling warning_with_optional_rust_toolchain_source

}
}

enum RustupToolchainSource {
Copy link
Member

Choose a reason for hiding this comment

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

As far as I know, rustup hasn't yet claimed those values are stable. At least the doc doesn't say anything more than the environment key https://github.com/rust-lang/rustup/blob/de2b979bd4569cacfabf501bb58464c9139b0d6d/doc/user-guide/src/environment-variables.md?plain=1#L75.

  • Could we have a link to the rustup source code if we want to make an assumption on that?
  • Should we check with the rustup team to ensure these value strings are stable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am happy to get confirmation from the Rustup team that the five values are stable, but would you feel more comfortable if they were listed directly in the documentation?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, thanks. But actually if we have #16131 (comment) maybe it is not really necessary?

Comment on lines +15 to +17
#[allow(clippy::disallowed_methods)]
let real_rustc = std::env::var("RUSTC").unwrap();
println!("cargo:rustc-env=REAL_RUSTC={real_rustc}");
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to REAL_RUSTUP_HOME, we shouldn't need a REAL_RUSTC because RUSTC (if it is set which it isn't guaranteed to be) is not cleared within the process that can also read REAL_RUSTC

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, cargo sets it on the build script and we are forwarding it along.

Copy link
Contributor

Choose a reason for hiding this comment

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

While a lot simpler of a solution, I'm not too thrilled with this because

  • say we could get rid of our build script for production reasons (which would be ideal), we'd then have production builds running a build script for tests
  • we have to use env! which I assume makes caching more difficult because it has an absolute path in it that can change, particularly for CI

Copy link
Contributor

Choose a reason for hiding this comment

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

@weihanglo your thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

The cache issue might be a deal-breaker. Thanks epage for calling that out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I switch back to the earlier approach then? The one that inspired #16131 (comment)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Something like the original.

The original code is written in an odd way (why remove env variables when they aren't present?) that is further compounded with the change to remove RUSTUP_* env variables in this PR.

I would move the RUSTUP_* env variable changes to the start of this PR and remove the env_remove calls in that commit as they are redundant. Feel free to even split that out into a separate PR so we can more quickly review and merge that while other parts of this are still under discussion as those changes stand on their own.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Feel free to even split that out into a separate PR...

It's #16469, but it's currently failing.

Regardless, should I remove the Clear RUSTUP_* environment variables in test_env commit from this PR and proceed with everything else?

Copy link
Contributor

Choose a reason for hiding this comment

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

Add RustupEnvironmentBuilder

When doing a refactor commit, particularly when the diff is more difficult to read (indentation level, moving), please separate out any logical changes into a separate commit

Copy link
Contributor

Choose a reason for hiding this comment

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

Set RUSTUP_TOOLCHAIN_SOURCE in rustup tests

Why is this needed?

We need to be able to work with old rustup that doesn't set this, so it is probably good for us to have some existing tests that leave it unset

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would be happy to get rid of the commit, but I don't know how to act on the "tests that leave it [RUSTUP_TOOLCHAIN_SOURCE] unset" comment.

Could you give me more guidance on tests would like to have once Rustup 1.29 is published?

Copy link
Contributor

Choose a reason for hiding this comment

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

Flip this around, why do we need this commit?

Cargo works with old and new rustup, so these shoudn't be required from the perspective of "need to mirror rustup exactly. cc2855c will clear RUSTUP_TOOLCHAIN_SOURCE so we don't need to worry about cargo test when cargo comes through the rustup proxy setting RUSTUP_TOOLCHAIN_SOURCE, causing the tests to be confused.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the .env("RUSTUP_TOOLCHAIN_SOURCE", ..) to simluate rustup's behavior, because I thought that was what the existing .env("RUSTUP_TOOLCHAIN", ..) just below them were meant to do.

But I appreciate what you are saying.

Should I just remove this commit then?

Copy link
Contributor

Choose a reason for hiding this comment

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

I lean towards removing it

This is the first of several commits to implement a fix for rust-lang#11036.
The changes fetch the `RUSTUP_TOOLCHAIN_SOURCE` environment variable set
by Rustup, and warn if it is anything other than "default" or "cli".
@smoelius smoelius force-pushed the second-half-of-11036 branch 2 times, most recently from e991fee to 488cb13 Compare January 1, 2026 12:38
@smoelius
Copy link
Contributor Author

smoelius commented Jan 1, 2026

I'm still cleaning up commits. Thanks for your patience.

@smoelius smoelius force-pushed the second-half-of-11036 branch from 488cb13 to ebfa8c5 Compare January 1, 2026 13:11
@smoelius smoelius force-pushed the second-half-of-11036 branch from ebfa8c5 to 13bd099 Compare January 1, 2026 13:19
@smoelius smoelius force-pushed the second-half-of-11036 branch from 13bd099 to 2e97d39 Compare January 1, 2026 13:34
@smoelius
Copy link
Contributor Author

smoelius commented Jan 1, 2026

I think the PR is ready to be looked at again.

Comment on lines +14 to +16
if let Some(val) = std::env::var_os("RUSTUP_HOME") {
p.env("RUSTUP_HOME", val);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed to be set on every cargo call?
(same for CargoProjectExt)

(thanks for splitting this out as it makes it easier to not miss details like this)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not setting RUSTUP_HOME in cargo_process causes the following tests to fail:

  • install::multiple_pkgs_path_set
  • install::relative_install_location_with_path_set

Not setting RUSTUP_HOME in CargoProjectExt causes the following tests to fail:

  • cargo_alias_config::alias_shadowing_external_subcommand
  • cargo_alias_config::builtin_alias_shadowing_external_subcommand
  • jobserver::runner_inherits_jobserver

Would you rather that the individual tests be modified?

Copy link
Contributor

Choose a reason for hiding this comment

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

Would you rather that the individual tests be modified?

Yes. In fact, I consider these tests failing suspect and should be evaluated. By setting RUSTUP_HOME explicitly, we at least isolate and identify these. We can then follow up by evaluating and adjusting as needed.

epage added a commit to epage/cargo that referenced this pull request Jan 2, 2026
Thought of this when reviewing new cases for `std::env` in rust-lang#16131.
&& !source.is_default()
&& !source.is_command_line_override()
{
#[allow(clippy::disallowed_methods)]
Copy link
Contributor

Choose a reason for hiding this comment

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

non-blocking (particularly with how late I thought of this): we should use expect and reason. I posted #16461 to migrate some cases over. The reason for this is "consistency with rustup".

@smoelius smoelius force-pushed the second-half-of-11036 branch from 2e97d39 to 79a32f6 Compare January 3, 2026 12:40
epage added a commit to epage/cargo that referenced this pull request Jan 5, 2026
Thought of this when reviewing new cases for `std::env` in rust-lang#16131.
epage added a commit to epage/cargo that referenced this pull request Jan 5, 2026
Thought of this when reviewing new cases for `std::env` in rust-lang#16131.
github-merge-queue bot pushed a commit that referenced this pull request Jan 5, 2026
### What does this PR try to resolve?

Thought of this when reviewing new cases for `std::env` in #16131.

### How to test and review this PR?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-infrastructure Area: infrastructure around the cargo repo, ci, releases, etc. A-testing-cargo-itself Area: cargo's tests Command-install S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants