Skip to content

Default implicit install restrictions #4264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ChrisDenton opened this issue Mar 24, 2025 · 4 comments
Open

Default implicit install restrictions #4264

ChrisDenton opened this issue Mar 24, 2025 · 4 comments
Milestone

Comments

@ChrisDenton
Copy link
Member

ChrisDenton commented Mar 24, 2025

Summary

This issue is intended to gather community feedback on the future direction of rustup's automatic install behaviour. It suggests some changes to the way rustup does implicit installs by default but these proposals are subject to change based on feedback.

Background

Currently rustup will implicitly install the active toolchain if it isn't installed already. This happens when you run almost any rustup command or using a tool managed by rustup, such as cargo or rustc (these are called "shims").

The active toolchain is usually controlled by the user. but, as detailed on the Overrides page of the book, a project can contain a rustup-toolchain.toml file to override the user's preference.

In this example of an override, we set the toolchain to use nightly-2025-03-20 for their current host:

[toolchain]
channel = "nightly-2025-03-20"

A toolchain override can also be a path to a custom toolchain:

[toolchain]
# `path` is relative to the project directory
path = "./my-toolchain"

Users can override this override using the + syntax (e.g. cargo +stable build) or by using rustup override.

Different projects use a rustup-toolchain.toml for different purposes. For example:

  • The project relies on unstable nightly features which are only guaranteed to work with a specific version.
  • It contains the MSRV. The project will compile with newer versions but the toolchain file records the lowest version that works.
  • It's for CI. The project wants to lock the rustc version used in CI.
  • A custom toolchain is required. Either to support platforms that don't have official build or for custom builds of official platforms.

How rustup is used

rustup is used in a variety of different contexts which may have different requirements. For example:

  • Interactively on the command line.
  • In non-interactive scripts.
  • In CI.
  • In the background by IDEs, e.g. for Language Server Protocols (LSPs) such as rust-analyzer

Additionally rustup can be used when either the user or systems has resource constraints:

  • Internet access is not available, unreliable, slow or otherwise undesirable
  • Drive space is limited or restricted in some way

Problems

Silent background installs

As mentioned above, IDEs use rustup in the background when they call cargo or rustc. This means that toolchains can be installed completely silently. This also means that downloads are more likely to occur concurrently with other uses of rustup. This can currently cause errors and other problems due to lack of filesystem locking but even when that is fixed it will cause the user to be blocked until the IDE finishes downloading a toolchain.

Trust

The current default implicitly trusts the rustup-toolchain.toml file. Since it's common to download projects from the internet, this is not a great default. Making this worse is the path override, which can mean implicitly trusting binaries downloaded from the internet without user intervention.

Control

Users should ultimately be in control of which toolchains are installed and used.

While it is possible to override rustup-toolchain.toml using rustup override, this isn't easy to discover naturally and in any case requires a lot more vigilance. The + syntax can also be used as an override but this requires remembering to use it for every single command that goes through rustup.

Next steps

These steps are intended to have minimal impact on current uses of rustup but take care of some edge cases. They do not address all the above issues.

  • If the project's rustup-toolchain.toml uses a path based toolchain then this will always require an explicit install if it's not installed already.
  • Only when running tools, such as cargo, should implicit installs happen. Explicit installs can be done via the rustup install command.
  • No other rustup commands should cause an implicit install (e.g. rustup --version).

Future possibilities

Trusting rustup-toolchain.toml

It would be good for the user to be given a choice on how they want to handle a rustup-toolchain.toml file in a project. E.g.:

  • Install once. The user will be prompted again the next time the file requires a new toolchain to be installed.
  • Always trust the rustup-toolchain.toml file. This will mean changes in the file can cause implicit installs of new toolchains
  • Ignore. The override will not take effect and the user's default toolchain will be used instead.

This would allow the user to have control over what gets installed on their system and to be able to easily user their preferred toolchain. The difficulty will be in providing a migration path, especially for CI.

Using --version on shims

Using --version on shims (such as cargo --version) should not trigger a download and install. People who use this intentionally to install toolchains should be migrated to rustup install, first with warnings and later becoming a hard error.

Unanswered questions

Interaction with the "safe file discovery" RFC

The Cargo and Rustup safe file discovery RFC proposes limiting the directories visited by cargo and rustup to just those owned by the user to protect against other users on the same system being able to tamper with the current users' builds. It suggests the RUSTUP_SAFE_DIRECTORIES and CARGO_SAFE_DIRECTORIES environment variables to opt-out of this. Should rustup reuse these for other meanings of "safe" or would conflating these concepts be confusing?

Prior art

direnv is a tool that allows environment variables to be configured using a file in the current directory. Users must use direnv allow . to allow this and do so again for changes.

@djc
Copy link
Contributor

djc commented Mar 24, 2025

@ChrisDenton sorry I wasn't able to give feedback on your earlier proposal. I think we should extend this substantially before we give it wider exposure, and I'm honestly more and more inclined to use the project RFC process for it.

Feedback on the current content:

  • I think we should more explicitly explain the 1.27.x state before moving on to problems. In particular, contexts where rustup is used (for example in the background in IDE LSPs, in CI setups).
  • For the Problems section, I think this probably also should be extended more. This also should talk about working offline and potential latency issues from implicit toolchain downloads.
  • We should then explain the changes made for 1.28.0 (everything explicit), and the proposed migration path.
  • Then, clarify the current state in 1.28.1/1.28.2.
  • The Initial Proposal (I find this title a little unclear since nothing about it is really "initial" -- maybe "Next steps") should talk about we make things more explicit again without breaking a bunch of users. Consider naming the bullets so they can more easily be referenced. I think I previously proposed the "only running tools" thing but it wasn't very popular because cargo --version is running a tool but is also maybe a lot like rustup --version in that it is querying the current state rather than assuming a certain state.

Should also discuss interaction with the safe directories RFC.

@ChrisDenton
Copy link
Member Author

My intent here is to gather feedback (definitely including substantial edits!) rather than going straight to a full RFC. An RFC seemed somewhat premature to me if there's still a lot of questioning of the premise and many ideas about which direction to go in. I definitely want to focus on the background/problems sections more than specific solutions at this point so expanding that is very useful.

I think I previously proposed the "only running tools" thing but it wasn't very popular because cargo --version is running a tool but is also maybe a lot like rustup --version in that it is querying the current state rather than assuming a certain state.

As an eventual goal, I agree. However for a "next step", I fear changing what cargo --version currently does would be more likely to cause issues.

@djc
Copy link
Contributor

djc commented Mar 24, 2025

As an eventual goal, I agree. However for a "next step", I fear changing what cargo --version currently does would be more likely to cause issues.

I am ambivalent about this kind of phasing. In a way, I think a single transition is helpful because you don't need users to update their stuff multiple times in (shortish) succession.

@ChrisDenton
Copy link
Member Author

The intent of the next steps is that almost nobody will need to change anything. Use of path in rust-toolchain.toml is rare whereas using cargo --version or rustc --version intentionally to trigger an install is more common today. Changing it would have more impact. We should encourage migration to rustup install for that (and in general). That is a single migration whether we change cargo --version upfront or later on.

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

No branches or pull requests

3 participants