Priority of directory override and rust-toolchain file

Some days ago, when Rust 1.47.0 was released, I installed it using a current version of rustup (1.22.1). I played a bit around, roughly I did the following

rustup toolchain install "1.46.0"

Create a rust project under '~/develop/test/' and change to that directory.

Set a directory override with 'rustup override set "stable"'.

Then I pinned the project to a specified release using a rust-toolchain file with 'echo "1.46.0" > rust-toolchain'.

When I run rustc I was a little bit surprised because I expected the pinned Rust version "1.46.0" NOT the current stable "1.47.0".

I checked it by running 'rustup show' and 'cat ~/.rustup/settings.toml'.

Both calls show me that the Rust version for the test project was the current "stable" release "1.47.0" (set with rustup override) NOT the pinned version "1.46.0" which I expected.

In the documentation is written that a directory override has a higher priority than a rust-toolchain file. (https://github.com/rust-lang/rustup/blob/master/doc/src/overrides.md)

 1. A toolchain override shorthand used on the command-line, such as cargo +beta.
 2. The RUSTUP_TOOLCHAIN environment variable.
 3. A directory override, set with the rustup override command.
 4. The rustup-toolchain file.
 5. The default toolchain.

My question now is, why have a directory override a higher priority than a local rust-toolchain file (if they point to the same directory)? What is the idea behind such a behavior?

Would it make sense to swap the priority for a directory override and a rust-toolchain file? Maybe such a behavior would feels more natural.

Swap the priority maybe have following advantage:

If a shared project was updated with a new rust-toolchain file to a newer Rust version, everyone automatically use the new version, even if the project directory was overridden with an different version using 'rustup override'.

A prominent example is Git, which can also optionally use a local project configuration .gitconfig, which have a higher priority than the other local and global config files.

Both files .gitconfig and rust-toolchain are designed to be shared in a project repository.

The following table compare the priority of the Git and Rust configurations.

Prio. Git config Rust config Description
1. git config --file cargo +stable
2. .gitconfig Directory override '~/.rustup/settings.toml' Local Git config file; local Rust settings in global config.
3. $GIT_DIR/config rust-toolchain Local config files.
4. ~/.gitconfig Default toolchain '~/.rustup/settings.toml' Global config files.

Hint: The .gitconfig file will only be used by Git when calling the following command once.

git config --local include.path ../.gitconfig

(https://git-scm.com/docs/git-config#_includes)

I think the current convention is oriented for the case where rust-toolchain is checked in to source control. This means everyone who clones the repo will be using that version. A directory override allows the local user to decide to use a different version if they want to. The model here is giving the local user more control over the defaults. If it was the other way around, it would be a bit more awkward to override (you'd have to use + syntax every time, or modify a source-controlled file which you may not want).

I don't think this can be directly compared to git, because .git/config isn't checked in.

I'm a bit confused, why are you setting a directory override if you don't want to use it?

2 Likes

Yes, I agree with you that the +syntax in this example is not the final solution. There must also be additional changes in the Rust toolchain to solve this in a flexible way.

In most cases editing a local config file under source control is not a problem. But if a user really wants to avoid editing such a file, it would be helpful to add a feature to flexible control the project configuration in the file system (not environment variables).

As I mentioned in my first post, Git provide a very flexible solution to add user defined configuration files (under source control or not). This means adding a second additional local config for example .gitconfig2 is possible. (https://git-scm.com/docs/git-config#_includes)

Another advantage of local config files is that the whole project directory can be easily moved to a different location in the file system without breaking anything e.g. the path for the directory override in the global configuration '~/.rustup/settings.toml'.

Yes, you cannot exactly compare Rust with Git but many applications fight with similar problems :wink: The focus was on local rust-toolchain and .gitconfig files.

Good point, but I did not know the behavior before, I only expect something different.

Anyway, I like the rust toolchain and in general it works great for me.