Skip to content

Conversation

smoelius
Copy link
Contributor

@smoelius smoelius commented Oct 6, 2025

This PR is in pursuit of rust-lang/cargo#11036. Specifically, it sets an environment variable RUST_TOOLCHAIN_SOURCE. The variable's content will be used to issue a warning when a cargo install is performed with a non-default toolchain.

The variable's content is one of cli, env, override, config, or default.

Nits are welcome.

cc: @epage

@smoelius smoelius marked this pull request as draft October 7, 2025 06:20
@smoelius
Copy link
Contributor Author

smoelius commented Oct 7, 2025

The variable's content has the form source toolchain

This is redundant, because the latter component is RUSTUP_TOOLCHAIN. I'll fix this PR in the next few hours.

EDIT: Done.

@smoelius smoelius marked this pull request as ready for review October 7, 2025 09:18
Comment on lines +617 to +620
/// Set the `RUSTUP_TOOLCHAIN_SOURCE` environment variable if not already set.
///
/// `RUSTUP_TOOLCHAIN_SOURCE` indicates how the toolchain was determined. The environment
/// variable could have been set in proxy_mode.rs, in which case it should not be changed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason we let the original through rather than override it?

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 think that's the behavior we want.

In my installation, all the proxies link to rustup:

lrwxrwxrwx 1 smoelius smoelius       32 Jan 31  2025 cargo -> /home/smoelius/.cargo/bin/rustup

So I think we want it to handle the + args and we should just let those through:

// Check for a + toolchain specifier
let arg1 = args.next();
let toolchain = arg1
.as_ref()
.map(|arg| arg.to_string_lossy())
.filter(|arg| arg.starts_with('+'))
.map(|name| ResolvableLocalToolchainName::try_from(&name.as_ref()[1..]))
.transpose()?;

I am happy to be corrected if I am misunderstanding.

Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if run cargo +beta test and one of my tests invokes cargo doc within a directory that has a rustup-toolchain.toml for nightly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

RUSTUP_TOOLCHAIN_SOURCE should be set to cli. But I don't think I understand the point of your question.

Copy link
Contributor

Choose a reason for hiding this comment

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

Within the cargo doc call, the source of the toolchain is config but RUSTUP_TOOLCHAIN_SOURCE will incorrectly report back cli because the outer most rustup call had it set on the CLI.

To me, it seems like we should only inherit RUSTUP_TOOLCHAIN_SOURCE if we are inheriting the parent's toolchain.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Within the cargo doc call, the source of the toolchain is config

I don't mean to question you but are you sure that's right?

I just tested in a configuration like you described with this program:

//! ```
//! let stdout = std::process::Command::new("env").output().unwrap().stdout;
//! std::fs::write("env.txt", stdout).unwrap();
//! ```

#[test]
fn test() {
    std::process::Command::new("cargo").arg("doc").status().unwrap();
}

And here is what I saw written to the env.txt file:

RUSTUP_HOME=/home/smoelius/.rustup
RUSTUP_TOOLCHAIN=beta-x86_64-unknown-linux-gnu
RUSTUP_TOOLCHAIN_SOURCE=cli

If I run with just cargo test instead of cargo +beta test, I observe what you describe.

Copy link
Contributor

Choose a reason for hiding this comment

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

If I run with just cargo test instead of cargo +beta test, I observe what you describe.

So my exact example didn't work but the principle still applies.

return;
}
if let Some(reason) = f() {
cmd.env("RUSTUP_TOOLCHAIN_SOURCE", reason.to_source());
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Or is that only env variables that rustup reads?

Are the ones it sets defined anywhere?

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 think both are in that list. I updated the list.

return;
}
if let Some(reason) = f() {
cmd.env("RUSTUP_TOOLCHAIN_SOURCE", reason.to_source());
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned in rust-lang/cargo#11036, RUSTUP_TOOLCHAIN_SOURCE could be taken as pointing to something inside the toolchain or pointing to what caused the toolchain to be set, not just the kind of toolchain source.

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 take your point. But I thought we wanted to let the rustup team decide on the variable name. So I have tried to remain agnostic on that front.

Comment on lines +109 to +113
Self::Default => "default",
Self::Environment => "env",
Self::CommandLine => "cli",
Self::OverrideDB(_) => "override",
Self::ToolchainFile(_) => "config",
Copy link
Contributor

Choose a reason for hiding this comment

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

This is redundant, because the latter component is RUSTUP_TOOLCHAIN. I'll fix this PR in the next few hours.

Huh, RUSTUP_TOOLCHAIN is documented as something the user can set; I didn't realize that rustup sets it on child processes but

cmd.env("RUSTUP_TOOLCHAIN", format!("{}", self.name));

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.

2 participants