Zum Inhalt springen

Rust-Fehler E0554: #![feature] may not be used on the stable release channel

E0554 bedeutet: Dein Code beginnt mit einer Zeile #![feature(...)], und so etwas akzeptiert nur die Nightly-Version von Rust. Fast immer kommt der Fehler aus kopiertem Code: aus einem Blogartikel, einem GitHub-Repo, einer KI-Antwort oder einer alten Antwort auf Stack Overflow. Dieser Code wurde für Nightly-Rust geschrieben, und du benutzt Stable, also das, was rustup standardmäßig installiert. Mit deiner Installation ist alles in Ordnung. Meistens löschst du einfach eine Zeile und erledigst dasselbe auf einem stabilen Weg. (Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.)

error[E0554]: `#![feature]` may not be used on the stable release channel
--> src/main.rs:1:1
|
1 | #![feature(iter_map_windows)] // ❌ copied from code written for nightly Rust
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Auf Deutsch: „#![feature] darf auf dem Stable-Kanal nicht benutzt werden.“ Der Kommentar im Code heißt: „kopiert aus Code, der für Nightly-Rust geschrieben wurde“.

Dieses Programm erzeugt den Fehler:

#![feature(iter_map_windows)] // ❌ copied from code written for nightly Rust
fn main() {
let temps = [18, 21, 19, 24];
let changes: Vec<i32> = temps.iter().map_windows(|[a, b]| *b - *a).collect();
println!("{:?}", changes);
}

Die ^^^ unterstreichen die ganze erste Zeile, #![feature(iter_map_windows)]. Diese Zeile ist eine Bitte: „Schalte bitte das unfertige Feature namens iter_map_windows ein.“ Nur der Nightly-Compiler nimmt solche Bitten an. Der „stable release channel“ (stabile Veröffentlichungskanal) in der Meldung ist das normale Rust, das du über rustup bekommst, und das lehnt ab.

Achte darauf, worüber rustc sich nicht beschwert: über map_windows in Zeile 5. rustc hält schon bei der Zeile #![feature] an. Erst wenn du diese Zeile entfernst, erfährst du, ob der restliche Code auf Stable funktioniert.

Auf dem Beta-Kanal bekommst du denselben Fehler. Hat dein Code mehrere #![feature]-Zeilen, meldet rustc meistens nur die erste. Schau also oben in der Datei nach, ob es noch mehr gibt.

Das ist wie ein Ausweis „Nur für Personal“. Die Versuchsküche (Nightly) lässt dich damit rein. Das Restaurant (Stable) akzeptiert solche Ausweise überhaupt nicht, egal wie höflich du ihn vorzeigst.

Rust verspricht: Code, der heute auf Stable kompiliert, kompiliert auch mit jeder künftigen stabilen 1.x-Version. Unfertige Features können nicht Teil dieses Versprechens sein. Ihre Namen, Argumente und ihr Verhalten können sich noch ändern, oder sie werden wieder entfernt. Deshalb gibt es sie nur auf Nightly, einer neuen Version des Compilers, die jede Nacht gebaut wird. Dort schaltest du jedes einzeln mit seinem Namen über #![feature(...)] ein.

Stable-Rust ignoriert die Zeile nicht einfach, sondern bricht mit einem Fehler ab. So kannst du kein Projekt auf einem unfertigen Feature aufbauen, ohne es zu merken. Ist ein Feature fertig, wird es Teil von Stable-Rust und braucht die Zeile überhaupt nicht mehr.

Wenn du E0554 siehst, gibt es also nur drei echte Fragen: Gibt es einen stabilen Weg (Lösung 1)? Ist das Feature schon stabil (Lösung 2)? Oder willst du wirklich Nightly (Lösung 3)? Siehe Stable, beta und nightly.

Lösung 1: Das Attribut entfernen und die stabile API benutzen

Abschnitt betitelt „Lösung 1: Das Attribut entfernen und die stabile API benutzen“

Nimm diese Lösung fast immer. Lösch die Zeile #![feature] und kompiliere noch einmal. Bekommst du jetzt E0658 (use of unstable library feature `iter_map_windows` ), ist das Feature noch unfertig, und du brauchst einen stabilen Weg für dasselbe. Die meisten instabilen Methoden sind Abkürzungen für etwas, das Stable-Rust schon kann. Hier liefert dir .windows(2) auf einem Slice jedes Paar benachbarter Elemente:

fn main() {
let temps = [18, 21, 19, 24];
let changes: Vec<i32> = temps.windows(2).map(|w| w[1] - w[0]).collect(); // ✅ stabil
println!("{:?}", changes);
for w in temps.windows(2) {
println!("{} -> {}", w[0], w[1]);
}
}

Ausgabe:

[3, -2, 5]
18 -> 21
21 -> 19
19 -> 24
▶ Selbst ausprobieren

Um den stabilen Weg zu finden, öffne die Methode in der Doku der Standardbibliothek. Instabile Elemente haben einen Kasten mit „This is a nightly-only experimental API“ (eine experimentelle API nur für Nightly), und der Feature-Name aus deiner #![feature]-Zeile passt meistens zu einer Seite in The Unstable Book (auf Englisch). Siehe Slices und Iteratoren.

Lösung 2: Prüfen, ob das Feature inzwischen stabil ist

Abschnitt betitelt „Lösung 2: Prüfen, ob das Feature inzwischen stabil ist“

Nimm diese Lösung, wenn der Code schon etwas älter ist. Viele Features, die früher #![feature] brauchten, gehören jetzt zu Stable-Rust, und dann ist die Zeile einfach überflüssig. rustc sagt dir das in einer Warnung direkt unter dem Fehler:

error[E0554]: `#![feature]` may not be used on the stable release channel
--> src/main.rs:2:1
|
2 | #![feature(slice_as_chunks)] // ❌ not needed any more: this feature is stable now
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: the feature `slice_as_chunks` has been stable since 1.88.0 and no longer requires an attribute to enable
--> src/main.rs:2:12
|
2 | #![feature(slice_as_chunks)] // ❌ not needed any more: this feature is stable now
| ^^^^^^^^^^^^^^^

Die Warnung heißt: „Das Feature slice_as_chunks ist seit 1.88.0 stabil und braucht kein Attribut mehr.“

Das fehlerhafte Programm (der Kommentar heißt: „nicht mehr nötig, dieses Feature ist jetzt stabil“):

// Copied from an older tutorial
#![feature(slice_as_chunks)] // ❌ not needed any more: this feature is stable now
fn main() {
let pixels = [255, 0, 0, 0, 128, 255];
let (rgb, _rest) = pixels.as_chunks::<3>();
for [r, g, b] in rgb {
println!("r={} g={} b={}", r, g, b);
}
}

Lösch die Zeile #![feature] (und den Kommentar darüber), und der Rest funktioniert unverändert:

fn main() {
let pixels = [255, 0, 0, 0, 128, 255];
let (rgb, _rest) = pixels.as_chunks::<3>(); // ✅ stabil seit Rust 1.88
for [r, g, b] in rgb {
println!("r={} g={} b={}", r, g, b);
}
}

Ausgabe:

r=255 g=0 b=0
r=0 g=128 b=255
▶ Selbst ausprobieren

Bei Sprach-Features ist rustc noch direkter: Unter dem Fehler steht help: remove the attribute (entferne das Attribut), dazu eine Zeile wie the feature `async_closure` has been stable since `1.85.0` and no longer requires an attribute to enable.

Keine Warnung, aber du vermutest, dass das Feature stabil ist? Vielleicht ist dein Rust einfach älter als die Version, in der es stabil wurde. Prüf das und aktualisiere:

Terminal window
rustc --version
rustup update

Zeigt rustc --version danach immer noch eine alte Version, hat das Projekt wahrscheinlich eine Datei rust-toolchain.toml, die sie festlegt. Siehe Eine Toolchain pro Projekt festlegen.

Nimm diese Lösung zuletzt: wenn es keinen stabilen Weg gibt und du in Kauf nimmst, dass dein Code mit einem künftigen Nightly kaputtgehen kann. Typische gute Gründe: Du probierst ein neues Feature aus, schreibst ein kleines Experiment, oder das Projekt, an dem du mitarbeitest, benutzt schon Nightly. Installier Nightly neben Stable und benutz es für einen einzelnen Befehl:

Terminal window
rustup toolchain install nightly
cargo +nightly run

Oder lass das ganze Projekt Nightly benutzen, mit einer Datei rust-toolchain.toml neben Cargo.toml. Dann nimmt ein einfaches cargo run in diesem Ordner Nightly und überall sonst Stable:

[toolchain]
channel = "nightly"

Bei einem Projekt, das auch andere bauen, leg ein Datum fest, etwa channel = "nightly-2026-10-01", damit alle denselben Compiler bekommen. Im Rust Playground wählst du Nightly im Toolchain-Menü.

Vielleicht stößt du auf den Rat, RUSTC_BOOTSTRAP=1 zu setzen, damit Stable #![feature] akzeptiert. Dieser Schalter ist dafür da, den Rust-Compiler selbst zu bauen. Damit hast du alle Risiken von Nightly und tust trotzdem so, als wärst du auf Stable. Lass es also.

Benchmarks mit #[bench]. Alte Anleitungen schreiben Benchmarks so, und #![feature(test)] gibt es weiterhin nur auf Nightly:

error[E0554]: `#![feature]` may not be used on the stable release channel
--> src/main.rs:3:1
|
3 | #![feature(test)] // ❌ built-in benchmarks are nightly-only
| ^^^^^^^^^^^^^^^^^
//! Price helpers.
//! Benchmark written the old way, for nightly Rust.
#![feature(test)] // ❌ built-in benchmarks are nightly-only
extern crate test;
fn total(prices: &[u32]) -> u32 {
prices.iter().sum()
}
#[bench]
fn bench_total(b: &mut test::Bencher) {
let prices: Vec<u32> = (1..1000).collect();
b.iter(|| total(&prices));
}
fn main() {
println!("{}", total(&[3, 4, 5]));
}

Lösung: Nimm ein Benchmark-Crate, das auf Stable funktioniert, etwa criterion oder divan, und starte cargo bench. Nur die Zeile #![feature] zu löschen reicht hier nicht: extern crate test; ergibt dann E0658 (use of unstable library feature `test` ). Siehe Performance.

Eine Abhängigkeit, die Nightly braucht. Zeigt die Zeile --> in ein Crate unter ~/.cargo/registry/ statt in dein eigenes src/, dann benutzt ein Crate, von dem du abhängst, #![feature]. Lösung: Schau in die README des Crates; oft funktioniert eine neuere Version auf Stable (zum Beispiel brauchte das Web-Framework Rocket bis Version 0.4 Nightly, und 0.5 läuft auf Stable). Sonst nimm ein anderes Crate. Siehe Cargo & Crates.

Kopierter Code mit #![feature(let_chains)]. Let Chains (if let Some(x) = a && x > 0) sind seit Rust 1.88 stabil, aber nur in der Edition 2024. Lösung: Lösch die Zeile (Lösung 2) und setz edition = "2024" in Cargo.toml. Sonst bekommst du let chains are only allowed in Rust 2024 or later.

  • E0658: use of unstable feature; das bekommst du meistens, nachdem du die Zeile #![feature] entfernt hast, wenn das Feature noch nur auf Nightly existiert.
  • E0599: no method found, wenn du die Zeile entfernst und die Methode wirklich nicht existiert oder aus einem Crate kommt, das du nicht hinzugefügt hast.
  • E0463: can’t find crate, wenn du auf criterion oder divan umsteigst und vergisst, es in Cargo.toml einzutragen.
  • E0435: attempt to use a non-constant value in a constant; ein häufiger Grund, warum Leute überhaupt nach Nightly-Features für Konstanten suchen.
  • Alle Compilerfehler: die vollständige Liste der Fehlerseiten.

Kurzer Check

1. Du fügst Code ein, der mit #![feature(try_blocks)] beginnt, und bekommst E0554. Was bedeutet das?

2. Unter dem Fehler warnt rustc, dass das Feature seit 1.88.0 stabil ist. Was solltest du tun?

3. Du willst für ein Experiment wirklich Nightly. Was ist der sauberste Weg?

Punkte: 0 / 3