Erreur Rust E0554 : #![feature] may not be used on the stable release channel (nightly)
E0554 veut dire : votre code commence par une ligne #![feature(...)], et seule la version nightly de Rust accepte ces lignes. Vous l’obtenez presque toujours avec du code copié : un article de blog, un dépôt GitHub, une réponse d’IA, une vieille réponse sur Stack Overflow. Ce code a été écrit pour Rust nightly, et vous êtes sur stable, la version que rustup installe par défaut. Votre installation n’a aucun problème. La solution consiste en général à supprimer une ligne et à faire la même chose d’une façon stable. Cette page fait partie du guide des erreurs du compilateur Rust.
Le message d’erreur
Section intitulée « Le message d’erreur »error[E0554]: `#![feature]` may not be used on the stable release channel --> src/main.rs:1:1 |1 | #![feature(iter_map_windows)] // ❌ copié depuis du code écrit pour Rust nightly | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Le compilateur vous dit : « #![feature] ne peut pas être utilisé sur le canal de distribution stable ».
Voici le programme qui la provoque :
#![feature(iter_map_windows)] // ❌ copié depuis du code écrit pour Rust nightly
fn main() { let temps = [18, 21, 19, 24]; let changes: Vec<i32> = temps.iter().map_windows(|[a, b]| *b - *a).collect(); println!("{:?}", changes);}Ce que ça veut dire
Section intitulée « Ce que ça veut dire »Les ^^^ soulignent toute la première ligne, #![feature(iter_map_windows)]. Cette ligne est une demande : « merci d’activer la fonctionnalité inachevée qui s’appelle iter_map_windows ». Seul le compilateur nightly accepte ce genre de demande. Le « stable release channel » (canal stable) du message, c’est le Rust normal que vous obtenez avec rustup, et il refuse.
Remarquez ce dont rustc ne se plaint pas : map_windows à la ligne 5. Il s’arrête d’abord à la ligne #![feature]. Une fois cette ligne supprimée, vous saurez si le reste du code marche sur stable.
Vous obtenez la même erreur sur le canal beta. Si votre code contient plusieurs lignes #![feature], rustc ne signale en général que la première : regardez donc s’il y en a d’autres en haut du fichier.
C’est comme un badge « réservé au personnel ». La cuisine d’essai (nightly) vous laisse entrer avec. Le restaurant (stable) n’accepte pas du tout ces badges, même si vous le montrez très poliment.
Pourquoi Rust fait ça
Section intitulée « Pourquoi Rust fait ça »Rust promet que le code qui compile aujourd’hui sur stable continuera de compiler sur toutes les futures versions stables 1.x. Les fonctionnalités inachevées ne peuvent pas faire partie de cette promesse : leur nom, leurs arguments et leur comportement peuvent encore changer, ou elles peuvent disparaître. Elles vivent donc seulement sur nightly, une nouvelle version du compilateur construite chaque nuit, et vous activez chacune par son nom avec #![feature(...)].
Rust stable n’ignore pas simplement la ligne : il s’arrête avec une erreur. Comme ça, vous ne pouvez pas construire un projet sur une fonctionnalité inachevée sans vous en rendre compte. Quand une fonctionnalité est terminée, elle entre dans Rust stable et n’a plus besoin de cette ligne.
Quand vous voyez E0554, il n’y a donc que trois vraies questions : existe-t-il une façon stable de le faire (solution 1), la fonctionnalité est-elle déjà stable (solution 2), ou voulez-vous vraiment nightly (solution 3) ? Voir Stable, beta et nightly.
Comment corriger
Section intitulée « Comment corriger »Solution 1 : supprimer l’attribut et utiliser l’API stable
Section intitulée « Solution 1 : supprimer l’attribut et utiliser l’API stable »Choisissez-la presque à chaque fois. Supprimez la ligne #![feature] et recompilez. Si vous obtenez maintenant E0658 (use of unstable library feature `iter_map_windows` ), la fonctionnalité est encore inachevée, et il vous faut une façon stable de faire la même chose. La plupart des méthodes instables sont des raccourcis pour quelque chose que Rust stable sait déjà faire. Ici, .windows(2) sur une slice vous donne chaque paire de voisins :
fn main() { let temps = [18, 21, 19, 24]; let changes: Vec<i32> = temps.windows(2).map(|w| w[1] - w[0]).collect(); // ✅ stable println!("{:?}", changes);
for w in temps.windows(2) { println!("{} -> {}", w[0], w[1]); }}Sortie :
[3, -2, 5]18 -> 2121 -> 1919 -> 24Pour trouver la façon stable, ouvrez la méthode dans la documentation de la bibliothèque standard. Les éléments instables ont un encadré qui dit « This is a nightly-only experimental API » (API expérimentale réservée à nightly), et le nom de la fonctionnalité dans votre ligne #![feature] correspond en général à une page de The Unstable Book (en anglais). Voir Les slices et Les itérateurs.
Solution 2 : vérifier si la fonctionnalité est devenue stable
Section intitulée « Solution 2 : vérifier si la fonctionnalité est devenue stable »Choisissez-la quand le code est un peu ancien. Beaucoup de fonctionnalités qui demandaient autrefois #![feature] font maintenant partie de Rust stable, et la ligne ne sert alors plus à rien. rustc vous le dit dans un avertissement, juste sous l’erreur :
error[E0554]: `#![feature]` may not be used on the stable release channel --> src/main.rs:2:1 |2 | #![feature(slice_as_chunks)] // ❌ inutile maintenant : cette fonctionnalité est stable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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)] // ❌ inutile maintenant : cette fonctionnalité est stable | ^^^^^^^^^^^^^^^L’avertissement dit : « la fonctionnalité slice_as_chunks est stable depuis la 1.88.0 et n’a plus besoin d’attribut pour être activée ».
Le programme qui la provoque :
// Copié depuis un ancien tutoriel#![feature(slice_as_chunks)] // ❌ inutile maintenant : cette fonctionnalité est stable
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); }}Supprimez la ligne #![feature] (et le commentaire au-dessus), et le reste marche sans changement :
fn main() { let pixels = [255, 0, 0, 0, 128, 255]; let (rgb, _rest) = pixels.as_chunks::<3>(); // ✅ stable depuis Rust 1.88 for [r, g, b] in rgb { println!("r={} g={} b={}", r, g, b); }}Sortie :
r=255 g=0 b=0r=0 g=128 b=255Pour les fonctionnalités du langage, rustc est encore plus direct : il ajoute help: remove the attribute (supprimez l’attribut) sous l’erreur, plus une ligne comme the feature `async_closure` has been stable since `1.85.0` and no longer requires an attribute to enable.
Pas d’avertissement, mais vous pensez que la fonctionnalité est stable ? Votre Rust est peut-être simplement plus ancien que la version où elle est devenue stable. Vérifiez et mettez à jour :
rustc --versionrustup updateSi rustc --version affiche encore une ancienne version après ça, le projet a sans doute un fichier rust-toolchain.toml qui la fixe. Voir Fixer une toolchain par projet.
Solution 3 : utiliser nightly exprès
Section intitulée « Solution 3 : utiliser nightly exprès »Choisissez-la en dernier, quand il n’existe aucune façon stable et que vous acceptez que votre code puisse casser avec une future version nightly. De bonnes raisons typiques : vous essayez une nouvelle fonctionnalité, vous écrivez une petite expérience, ou le projet auquel vous contribuez utilise déjà nightly. Installez nightly à côté de stable et utilisez-le pour une seule commande :
rustup toolchain install nightlycargo +nightly runOu faites utiliser nightly à tout le projet avec un fichier rust-toolchain.toml à côté de Cargo.toml. Un simple cargo run choisit alors nightly dans ce dossier, et stable partout ailleurs :
[toolchain]channel = "nightly"Pour un projet que d’autres personnes compilent aussi, fixez une date, comme channel = "nightly-2026-10-01", pour que tout le monde ait le même compilateur. Sur le Rust Playground, choisissez Nightly dans le menu de la toolchain.
Vous trouverez peut-être le conseil de définir RUSTC_BOOTSTRAP=1 pour que stable accepte #![feature]. Ce réglage existe pour compiler le compilateur Rust lui-même. L’utiliser vous donne tous les risques de nightly en faisant semblant d’être sur stable : ne le faites pas.
Où vous le verrez souvent
Section intitulée « Où vous le verrez souvent »Les benchmarks avec #[bench]. Les anciens guides écrivent les benchmarks (mesures de performance) comme ça, et #![feature(test)] est toujours réservé à nightly :
error[E0554]: `#![feature]` may not be used on the stable release channel --> src/main.rs:3:1 |3 | #![feature(test)] // ❌ les benchmarks intégrés sont réservés à nightly | ^^^^^^^^^^^^^^^^^//! Fonctions d'aide pour les prix.//! Benchmark écrit à l'ancienne, pour Rust nightly.#![feature(test)] // ❌ les benchmarks intégrés sont réservés à nightlyextern 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]));}Solution : utilisez une crate de benchmark qui marche sur stable, comme criterion ou divan, et lancez cargo bench. Supprimer seulement la ligne #![feature] ne suffit pas ici : extern crate test; donne alors E0658 (use of unstable library feature `test` ). Voir La performance.
Une dépendance qui a besoin de nightly. Si la ligne --> pointe dans une crate sous ~/.cargo/registry/ au lieu de votre propre src/, c’est une crate dont vous dépendez qui utilise #![feature]. Solution : regardez le README de la crate ; souvent une version plus récente marche sur stable (par exemple, le framework web Rocket avait besoin de nightly jusqu’à la 0.4, et la 0.5 tourne sur stable). Sinon, choisissez une autre crate. Voir Cargo et les crates.
Du code copié avec #![feature(let_chains)]. Les let chains (if let Some(x) = a && x > 0) sont devenues stables dans Rust 1.88, mais seulement dans l’édition 2024. Solution : supprimez la ligne (solution 2) et mettez edition = "2024" dans Cargo.toml. Sans ça, vous obtenez let chains are only allowed in Rust 2024 or later (les let chains ne sont permises qu’à partir de Rust 2024).
Erreurs liées
Section intitulée « Erreurs liées »- E0658 : use of unstable feature : ce que vous obtenez en général après avoir supprimé la ligne
#![feature], si la fonctionnalité est encore réservée à nightly. - E0599 : no method found : si vous supprimez la ligne et que la méthode n’existe vraiment pas, ou vient d’une crate que vous n’avez pas ajoutée.
- E0463 : can’t find crate : si vous passez à
criterionoudivanet oubliez de l’ajouter dansCargo.toml. - E0435 : attempt to use a non-constant value in a constant : une raison fréquente pour laquelle on va chercher des fonctionnalités
constde nightly au départ. - Toutes les erreurs du compilateur : la liste complète des pages d’erreurs.
Petit quiz
Section intitulée « Petit quiz »Petit quiz
1. Vous collez du code qui commence par #![feature(try_blocks)] et vous obtenez E0554. Qu'est-ce que ça veut dire ?
2. Sous l'erreur, rustc avertit que la fonctionnalité est stable depuis la 1.88.0. Que devez-vous faire ?
3. Vous voulez vraiment nightly pour une expérience. Quelle est la façon la plus propre ?
Score : 0 / 3
Pour aller plus loin
Section intitulée « Pour aller plus loin »- E0554 — Rust error codes index (en anglais) : l’explication officielle : les attributs de fonctionnalité ne sont permis que sur le canal nightly.
- How Rust is Made and “Nightly Rust” — The Rust Book (en anglais) : les canaux stable, beta et nightly, et comment une fonctionnalité passe de nightly à stable.
- Channels — The rustup book (en anglais) : installer nightly et l’utiliser à côté de stable.
- The toolchain file — The rustup book (en anglais) : comment
rust-toolchain.tomlchoisit le compilateur pour un projet, y compris un nightly fixé à une date. - The Unstable Book (en anglais) : tous les noms de fonctionnalités que vous pouvez mettre dans
#![feature], avec un lien vers leur ticket de suivi.