Skip to content

rustup default nightly: what that actually decides

Level: 201 · working knowledge

One line: rustup default nightly does not turn nightly on for your project — it changes the compiler for every Rust project on the machine, including ones you did not write, and it is the only toolchain choice that is recorded nowhere near the code it affects.

Nightly gets recommended a lot, and the recommendation is usually sound: it is where the interesting features are, and Rust's nightly is far more solid than the word suggests. The part worth slowing down on is not whether to use nightly — it is which of three quite different commands you reach for, because they are routinely treated as interchangeable and they are not.

Three scopes, one of which is invisible

What you want Command Who is affected Where it is written down
Nightly for this one command cargo +nightly build that invocation in the command, in front of you
Nightly for this project channel = "nightly-2026-08-11" in rust-toolchain.toml everyone who clones it in the repository, in version control
Nightly for everything rustup default nightly every Rust project on the machine nowhere

The right-hand column is the whole page. Rows one and two leave evidence: a reader of the command or of the repository can see which compiler was used. Row three leaves none — the fact lives in ~/.rustup/settings.toml, which is not in anybody's repository, is not in your shell history a month later, and is not visible to the colleague reading your bug report.

That asymmetry is why the middle row is almost always the one you want. It is also nightly. It just says so out loud, and it says so to everyone.

What nightly actually is

A build from Rust's master branch, published most nights, carrying no stability promise: #![feature(...)] is accepted, and a feature can change or disappear between two of them. It is genuinely reliable day to day — this is not a warning about crashes. Three specific things go wrong, and none of them announce themselves.

Your formatting silently stops matching CI's. rustfmt's unstable options are usable on nightly and ignored on stable — placed in a rustfmt.toml, they are applied on nightly and skipped with a warning on stable ↗. So a nightly machine formats one way, a stable CI runner checks for another, and cargo fmt -- --check fails on a diff the author cannot reproduce. See Formatting for the check this breaks.

"Nightly" may not mean last night. Components like clippy and rust-analyzer are not built successfully every night. When one is missing, rustup does not fail — it searches backwards for an older nightly that has it ↗ and installs that instead. So the compiler you get is some recent nightly, chosen by which components happened to build, and it can differ between two machines that ran the same command on the same day. Reproducibility that quietly depends on a build farm's luck is not reproducibility.

Unstable features become reachable, and reach is enough. You will not add #![feature(...)] by accident. But a -Z flag copied into .cargo/config.toml is accepted rather than rejected, a dependency's nightly-only path may light up, and none of it fails until somebody on stable tries to build. The library's compile times page already declines nightly's -Z threads=8 in CI for the neighbouring reason: a nondeterministic compiler is a debugging nightmare wearing a build failure's clothes.

When nightly is right

  • You need a specific unstable feature, and you can name it. That is a real reason and it is the common one.
  • You are testing your own crate against upcoming Rust, which is what beta and nightly exist for.
  • A tool you depend on requires it — miri, some proc-macro tooling, the parallel front end.
  • The project has decided on nightly as policy, in which case it belongs in the toolchain file where the decision is visible.

In every one of those, put it in rust-toolchain.toml, not in rustup default.

And pin the date

If you use nightly, use a dated one:

[toolchain]
channel = "nightly-2026-08-11"
components = ["rustc", "cargo", "clippy", "rustfmt", "rust-analyzer"]

The convention is not arbitrary — nightly identifies itself by date. rustup default nightly prints back rustc 1.99.0-nightly (3d6c19bb9 2026-08-11), because with nightly the version number alone does not identify the compiler and everyone involved knows it. Writing the date down is agreeing with the toolchain about what it just told you.

If you are coming from another language

  • Python — the parallel is running 3.15.0a1 as your system Python rather than in one project's virtualenv. Nobody does that, and the reason is the same: the blast radius is every project on the machine, and the choice is invisible from inside any of them.
  • ABAP — there is no nightly to opt into; the kernel is whatever the landscape runs. What Rust adds is the ability to choose, and therefore the obligation to record the choice.

See also


No generated output block: nothing on this page is a program's output, and the one transcript quoted — the nightly version string — comes from the slide that prompted the page rather than from a run on this machine, which has only stable installed.

Po polsku

Pytanie nie brzmi „czy nightly”, tylko w jakim zasięgu i gdzie ta decyzja zostaje zapisana. Nazwy kanałów (stable, beta, nightly) zostają po angielsku, bo to identyfikatory, które wpisuje się w plik, ale trzy sposoby ich użycia różnią się właśnie zasięgiem: cargo +nightly build dotyczy jednego wywołania i widać go w poleceniu; channel = "nightly-…" w rust-toolchain.toml dotyczy projektu i jedzie razem z nim w repozytorium; rustup default nightly przestawia kompilator każdemu projektowi Rusta na maszynie — także tym, których nie napisałeś — i nie zostawia po sobie żadnego śladu tam, gdzie ktokolwiek by go szukał. Fakt ten mieszka w ~/.rustup/settings.toml: nie ma go w żadnym repozytorium, nie ma go w historii powłoki miesiąc później i nie widzi go osoba czytająca twoje zgłoszenie błędu. Dlatego środkowy wiersz tabeli jest niemal zawsze tym właściwym — to też jest nightly, tyle że powiedziane na głos i wszystkim.

Same nightly nie należy się bać: to zwykły build z gałęzi master, publikowany prawie co noc, na co dzień solidny — nie chodzi tu o wysypywanie się kompilatora. Kłopoty są cichsze i są trzy. Po pierwsze, formatowanie przestaje zgadzać się z CI: niestabilne opcje rustfmt działają na nightly, a na stable są ignorowane z ostrzeżeniem, więc cargo fmt -- --check wywala się na różnicy, której autor u siebie nie potrafi odtworzyć. Po drugie — i to jest najostrzejszy fakt na tej stronie — „nightly” nie musi znaczyć „z zeszłej nocy”: gdy clippy albo rust-analyzer się danej nocy nie zbudował, rustup nie zgłasza błędu, tylko cofa się wstecz po starszy nightly, w którym te komponenty są. Dwie osoby, które tego samego dnia wpisały to samo polecenie, mogą mieć różne kompilatory — a odtwarzalność zależna od szczęścia farmy buildowej nie jest odtwarzalnością. Po trzecie, rzeczy niestabilne stają się osiągalne: flaga -Z wklejona do .cargo/config.toml zostanie przyjęta zamiast odrzucona i nic nie pęknie aż do chwili, gdy ktoś na stable spróbuje to zbudować.

Kiedy nightly jest uzasadnione — potrzebujesz konkretnej, dającej się nazwać funkcji spod #![feature(...)], testujesz swój crate pod nadchodzącego Rusta, albo wymaga go narzędzie w rodzaju miri — wpisz go do rust-toolchain.toml, z datą: channel = "nightly-2026-08-11". Ta konwencja nie jest widzimisię: nightly sam przedstawia się datą (rustc 1.99.0-nightly (3d6c19bb9 2026-08-11)), bo przy tym kanale numer wersji nikogo nie identyfikuje. Zapisanie daty to po prostu przyznanie toolchainowi racji co do tego, co przed chwilą o sobie powiedział.

Szukaj po polsku: kanały rustupa · nightly w Ruscie · rust-toolchain.toml channel nightly · rustup default nightly · rustfmt unstable options nightly only