Le type never de Rust, expliqué
Le type never de Rust, écrit !, est le type du code qui ne produit jamais de valeur. Il est stable dans Rust 1.100 après dix ans, et il change le repli de type.
5 min de lecture

En chiffres
- RFC 1216 proposed making ! a real type
- 2015
- crates crater compiled against the stabilization
- 9,024
- of them flagged as regressions
- 3,277
Le type never de Rust est le type d'une expression qui ne produit jamais de valeur. Il s'écrit avec un simple point d'exclamation, !. Une fonction qui panique toujours, boucle indéfiniment ou sort tôt a ce type, parce qu'elle ne rend jamais de valeur au code qui la suit. Après dix ans comme fonctionnalité instable, le type never est désormais stable. La pull request qui l'a fait a été fusionnée le 24 août 2026, et elle emporte avec elle une rupture de compatibilité.
Cela compte au-delà de la simple curiosité de compilateur. Le type never décide de ce qui se passe dans les impasses de votre code, et la nouvelle règle de repli peut changer ce qu'une fonction générique infère. La Rust Reference définit ! comme un type sans valeurs, représentant des calculs qui ne se terminent jamais.
Comment cela fonctionne
Un type est un ensemble de valeurs possibles. Le type bool en a deux. Le type never n'en a aucune. La RFC 1216, la proposition de 2015 qui a tout lancé, appelle un tel type un type vide, « un type pour lequel il n'existe rien de ce type ». Rien de type ! ne peut exister pendant l'exécution d'un programme, si bien qu'une valeur de ce type n'a aucune représentation au niveau machine.
Ce vide donne à ! son unique pouvoir spécial. Selon la documentation de la bibliothèque standard de Rust, une expression de type ! peut être convertie par coercition vers n'importe quel autre type. Le compilateur peut le promettre sans risque, parce que la coercition n'a jamais à s'exécuter. Si le code après un panic!() attend une String, l'expression de panique convient, puisqu'aucune String ne sera jamais nécessaire à cet endroit. C'est pourquoi return, break, continue et panic!() peuvent tous se trouver à une position qui attend un autre type.
La bibliothèque standard documente que ! implémente Clone, Copy, Debug, Display, Eq, Hash, Ord, PartialEq, PartialOrd et Error. La même documentation nomme un trait qu'il ne devrait jamais implémenter : Default. Default doit produire une valeur, et ! ne le peut pas.
Avant cette stabilisation, Rust stable ne vous laissait écrire ! qu'à un seul endroit, comme type de retour d'une fonction, selon la Reference. Les développeurs qui avaient besoin d'un type vide ailleurs écrivaient le leur, généralement enum Never {}, un motif que la RFC 1216 décrit. La version propre à la bibliothèque standard est std::convert::Infallible, une énumération sans variantes présente dans la bibliothèque depuis Rust 1.34.0. Sa documentation la décrit comme le type d'erreur pour les erreurs qui ne peuvent jamais se produire. Un Result<T, Infallible> dit au lecteur que le résultat est toujours Ok.
Ce qui a changé, et quand
Trois choses sont arrivées ensemble dans la pull request 155499, selon la PR. Premièrement, ! est stable comme type à part entière, ce que la RFC 1216 demandait en 2015. Deuxièmement, Infallible devient un alias de type pour !, si bien que les deux noms désignent désormais le même type. Troisièmement, et c'est la partie qui casse, le repli de type se résout désormais vers ! dans toutes les éditions de Rust.
Le repli est la règle pour un cas limite. Le compilateur atteint parfois un endroit où une expression diverge et où rien autour ne fixe un type. Historiquement, il choisissait là le type unit (), le tuple vide. Dans l'édition 2024 et les suivantes, la documentation de la bibliothèque standard décrit déjà le repli comme ! à la place. La PR de stabilisation en fait la règle partout, y compris dans les éditions plus anciennes.
Le projet Rust a mesuré le changement avant de le fusionner. La PR fait état d'une exécution de crater sur 9 024 crates. crater compile un large échantillon de crates publiées face à un compilateur proposé et signale ce qui casse. Il a signalé 3 277 régressions et aucune correction. La PR est prévue pour Rust 1.100.0, comme l'article de Tech AI Wire sur la stabilisation le notait lors de sa fusion.
Un rapport de régression est instructif. Un contributeur a signalé que cargo-semver-checks, un outil qui vérifie les crates à la recherche de changements d'API incompatibles, rapportait le changement sur Infallible comme une rupture. La discussion de la PR qualifie cela de faux positif. Comme l'a formulé le contributeur JonathanBrouwer, « Le type est toujours là, il est simplement passé d'un pub enum à un pub type. »
| Jalon | Quand | Ce qui s'est passé |
|---|---|---|
| RFC 1216 | 19 juillet 2015 | Proposition de promouvoir ! en type à part entière |
| Ticket de suivi 35121 | 29 juillet 2016 | Ouvert pour suivre la RFC ; la PR 35162 a été la première implémentation |
| PR 65355 | Rust 1.41.0 | Première stabilisation, annulée dans la PR 67224 après des régressions |
| Édition Rust 2024 | Édition 2024 | Repli modifié vers ! d'abord dans la nouvelle édition |
| PR 155499 | 24 août 2026 | ! stable, repli universel, Infallible devenu alias |
Pourquoi cela a pris dix ans
Le ticket de suivi raconte l'histoire du retard. Le ticket 35121 a été ouvert le 29 juillet 2016. Une première stabilisation a été livrée dans Rust 1.41.0, puis retirée, parce que de vraies crates ont cassé. Le ticket consigne le déclencheur : une conversion Error depuis Infallible a cessé de compiler, signalée comme le ticket 66757. L'auteur de la PR finale écrit sur son blog qu'il y a eu cinq tentatives ratées en tout. Cette dernière poussée lui a pris plus de deux ans.
La solution a été de procéder par étapes. Le ticket de suivi expose un plan en trois phases. Changer le repli vers ! dans la seule édition 2024. Stabiliser cette édition. Puis, une fois que l'écosystème avait absorbé la nouvelle règle, généraliser les ruptures de compatibilité et poser Infallible égal à !. La PR d'août 2026 est cette phase finale. L'autre grand changement du compilateur de Rust cette année, le solveur de traits de nouvelle génération, passe d'abord par nightly avec la même prudence, sa stabilisation étant prévue pour plus tard.
Ce que cela signifie pour les développeurs
Vérifiez le code générique sur nightly avant que Rust 1.100.0 n'arrive en stable. Le changement de repli compte là où un paramètre de type n'est fixé que par une expression qui panique ou qui sort tôt. À ces endroits, le compilateur choisissait () pour vous et choisit maintenant !. La plupart du code ne remarquera rien. Le code qui dépendait de l'ancien choix peut échouer à compiler, ou choisir une autre implémentation de trait. Les 3 277 cas relevés par crater montrent que ce n'est pas hypothétique.
Cherchez Infallible par grep. Si votre crate implémente un trait à la fois pour Infallible et pour !, ces deux implémentations entrent désormais en conflit, parce qu'elles nomment un seul type. La documentation d'Infallible note aussi que des types de pointeur de fonction comme fn() -> ! et fn() -> Infallible pouvaient porter des implémentations de trait différentes. Ceux-là coïncident désormais aussi. Une bibliothèque qui expose Infallible dans son API publique ne casse pas ses utilisateurs, quoi qu'en dise un outil de semver. Le type est toujours là sous les deux noms.
Utilisez ! à dessein à partir de maintenant. Une fonction qui ne peut que réussir peut renvoyer Result<T, !>, ce que la RFC 1216 cite comme cas d'usage motivant, et les appelants peuvent faire un match sur le seul bras Ok. Un gestionnaire qui ne retourne jamais peut être passé à du code générique attendant un Fn() -> T, un autre cas d'usage de la RFC, sans type enveloppe. Abandonnez le enum Never {} maison dès que votre version minimale de Rust prise en charge le permet.
Dix ans, c'est long pour un type d'un seul caractère. La première tentative annulée, le déploiement passé d'abord par une édition et le chiffre de crater en expliquent l'essentiel. C'est aussi pourquoi c'est un changement auquel vous pouvez vous préparer sur nightly dès aujourd'hui, avant qu'il n'arrive en stable.
Sources
- Never type - The Rust Reference - The Rust Reference
- Primitive type ! - Rust standard library documentation - Rust standard library docs
- RFC 1216: Promote ! to a type - Rust RFCs
- stabilize never type (PR #155499) - GitHub - rust-lang/rust
- Tracking issue for RFC 1216 (promoting ! to a type) - GitHub - rust-lang/rust
- Enum std::convert::Infallible - Rust standard library documentation - Rust standard library docs
Articles liés

Rust stabilise le type never après dix ans et cinq tentatives
Le type never est stable et Infallible en devient un alias. Le hic est une rupture dans le repli de type, que crater a signalée sur 3 277 crates.

Rust active son solveur de traits de nouvelle génération dans les builds nightly
Le nouveau solveur de traits de Rust est désormais activé par défaut en nightly - le plus grand changement du compilateur depuis la 1.0, quatre ans de travail, stabilisation prévue d'ici quelques mois.

La réécriture de mold en Rust vise l'éditeur de liens par défaut de Linux
Mold établit les liens 4,9 fois plus vite que LLVM lld. Son auteur le réécrit en Rust et veut que les distributions l'installent comme /usr/bin/ld.