Skip to content
Tech AI Wire
CodingErklärt

Rusts Never-Type, erklärt

Rusts Never-Type, geschrieben !, ist der Typ von Code, der niemals einen Wert liefert. Er ist nach zehn Jahren in Rust 1.100 stabil und ändert den Type-Fallback.

Von Tech AI Wire Team

5 Min. Lesezeit

XLinkedIn
Five dark gray squares in a row that lighten from left to right, ending in a single solid red square.

Die Zahlen

RFC 1216 proposed making ! a real type
2015
crates crater compiled against the stabilization
9,024
of them flagged as regressions
3,277

Rusts Never-Type ist der Typ eines Ausdrucks, der niemals einen Wert liefert. Er wird als einzelnes Ausrufezeichen geschrieben, !. Eine Funktion, die immer panikt, endlos läuft oder vorzeitig zurückkehrt, hat diesen Typ, weil sie dem folgenden Code niemals einen Wert zurückgibt. Nach zehn Jahren als instabiles Feature ist der Never-Type jetzt stabil. Der Pull Request, der das umgesetzt hat, wurde am 24. August 2026 gemergt und bringt eine brechende Änderung mit.

Das ist mehr als Compiler-Trivia. Der Never-Type entscheidet, was an den Sackgassen in Ihrem Code passiert, und die neue Fallback-Regel kann ändern, was eine generische Funktion herleitet. Die Rust Reference definiert ! als Typ ohne Werte, der Berechnungen darstellt, die niemals abgeschlossen werden.

Wie es funktioniert

Ein Typ ist eine Menge möglicher Werte. Der Typ bool hat zwei davon. Der Never-Type hat keinen. RFC 1216, der Vorschlag aus dem Jahr 2015, mit dem alles begann, nennt einen solchen Typ einen leeren Typ, „einen Typ, für den es nichts von diesem Typ gibt“. Nichts vom Typ ! kann existieren, während ein Programm läuft, also hat ein Wert dieses Typs überhaupt keine Repräsentation auf Maschinenebene.

Diese Leere gibt ! seine eine besondere Fähigkeit. Laut der Dokumentation der Rust-Standardbibliothek kann ein Ausdruck vom Typ ! per Coercion in jeden anderen Typ überführt werden. Der Compiler kann das sicher versprechen, weil die Coercion niemals ausgeführt werden muss. Wenn der Code nach einem panic!() einen String erwartet, passt der Panic-Ausdruck, denn dort wird niemals ein String gebraucht. Deshalb können return, break, continue und panic!() alle an einer Stelle stehen, die einen anderen Typ erwartet.

Die Standardbibliothek dokumentiert, dass ! Clone, Copy, Debug, Display, Eq, Hash, Ord, PartialEq, PartialOrd und Error implementiert. Dieselbe Dokumentation nennt einen Trait, den er niemals implementieren sollte: Default. Default muss einen Wert liefern, und ! kann das nicht.

Vor dieser Stabilisierung ließ Stable Rust ! laut der Reference nur an einer Stelle zu, als Rückgabetyp einer Funktion. Wer anderswo einen leeren Typ brauchte, schrieb sich einen eigenen, meist enum Never {}, ein Muster, das RFC 1216 beschreibt. Die eigene Version der Standardbibliothek ist std::convert::Infallible, ein Enum ohne Varianten, das seit Rust 1.34.0 in der Bibliothek ist. Seine Dokumentation beschreibt es als den Fehlertyp für Fehler, die niemals auftreten können. Ein Result<T, Infallible> sagt dem Leser, dass das Ergebnis immer Ok ist.

Was sich geändert hat und wann

Laut dem PR landeten drei Dinge zusammen in Pull Request 155499. Erstens ist ! als vollwertiger Typ stabil, was RFC 1216 im Jahr 2015 gefordert hatte. Zweitens wird Infallible ein Typ-Alias für !, sodass die beiden Namen jetzt denselben Typ bezeichnen. Drittens, und das ist der brechende Teil, löst der Type-Fallback jetzt in jeder Rust-Edition zu ! auf.

Der Fallback ist die Regel für einen Grenzfall. Manchmal erreicht der Compiler eine Stelle, an der ein Ausdruck divergiert und nichts in seiner Umgebung einen Typ festlegt. Historisch wählte er dort den Unit-Typ (), das leere Tupel. Für die Edition 2024 und später beschreibt die Dokumentation der Standardbibliothek den Fallback bereits stattdessen als !. Der Stabilisierungs-PR macht das überall zur Regel, auch in älteren Editionen.

Das Rust-Projekt hat die Änderung vor dem Merge gemessen. Der PR berichtet von einem crater-Lauf über 9.024 Crates. crater kompiliert eine große Stichprobe veröffentlichter Crates gegen einen vorgeschlagenen Compiler und meldet, was bricht. Es markierte 3.277 Regressionen und keine Fixes. Der PR ist für Rust 1.100.0 eingeplant, wie der Bericht von Tech AI Wire zur Stabilisierung beim Merge festhielt.

Ein Regressionsbericht ist lehrreich. Ein Mitwirkender meldete, dass cargo-semver-checks, ein Werkzeug, das Crates auf brechende API-Änderungen prüft, die Änderung an Infallible als brechend einstufte. Die Diskussion im PR nennt das einen Fehlalarm. Der Mitwirkende JonathanBrouwer formulierte es so: „Der Typ ist noch da, er hat sich nur von einem pub enum in einen pub type verwandelt.“

MeilensteinWannWas passierte
RFC 121619. Juli 2015Vorschlag, ! zu einem vollwertigen Typ zu befördern
Tracking-Issue 3512129. Juli 2016Eröffnet, um den RFC zu verfolgen; PR 35162 war die erste Implementierung
PR 65355Rust 1.41.0Erste Stabilisierung, nach Regressionen in PR 67224 zurückgenommen
Edition Rust 2024Edition 2024Fallback zuerst innerhalb der neuen Edition auf ! geändert
PR 15549924. August 2026! stabil, Fallback allgemein, Infallible als Alias

Warum es zehn Jahre dauerte

Das Tracking-Issue erzählt die Geschichte der Verzögerung. Issue 35121 wurde am 29. Juli 2016 eröffnet. Eine erste Stabilisierung erschien in Rust 1.41.0 und wurde dann wieder herausgenommen, weil echte Crates brachen. Das Issue hält den Auslöser fest: Eine Error-Konvertierung aus Infallible kompilierte nicht mehr, gemeldet als Issue 66757. Der Autor des endgültigen PR schreibt im eigenen Blog, dass es insgesamt fünf gescheiterte Versuche gab. Dieser letzte Anlauf dauerte mehr als zwei Jahre.

Der Ausweg war ein gestuftes Vorgehen. Das Tracking-Issue legt einen Plan in drei Phasen dar. Den Fallback nur innerhalb der Edition 2024 auf ! ändern. Diese Edition stabilisieren. Dann, sobald das Ökosystem die neue Regel aufgenommen hatte, die brechenden Änderungen allgemein machen und Infallible gleich ! setzen. Der PR vom August 2026 ist diese letzte Phase. Rusts andere große Compiler-Änderung dieses Jahres, der Trait-Solver der nächsten Generation, durchläuft auf dieselbe vorsichtige Weise zuerst Nightly, mit einer für später geplanten Stabilisierung.

Was das für Entwickler bedeutet

Prüfen Sie generischen Code auf Nightly, bevor Rust 1.100.0 Stable erreicht. Die Fallback-Änderung zählt dort, wo ein Typparameter nur durch einen Ausdruck festgelegt wird, der panikt oder früh zurückkehrt. An diesen Stellen wählte der Compiler früher () für Sie und wählt jetzt !. Der meiste Code wird nichts bemerken. Code, der sich auf die alte Wahl verließ, kann nicht mehr kompilieren oder eine andere Trait-Implementierung wählen. Die 3.277 crater-Treffer zeigen, dass das nicht hypothetisch ist.

Greppen Sie nach Infallible. Wenn Ihr Crate einen Trait sowohl für Infallible als auch für ! implementiert, kollidieren diese beiden Implementierungen jetzt, weil sie einen einzigen Typ benennen. Die Infallible-Dokumentation merkt außerdem an, dass Funktionszeiger-Typen wie fn() -> ! und fn() -> Infallible unterschiedliche Trait-Implementierungen tragen konnten. Auch die stimmen jetzt überein. Eine Bibliothek, die Infallible in ihrer öffentlichen API exponiert, bricht ihre Nutzer nicht, was auch immer ein Semver-Werkzeug sagt. Der Typ ist unter beiden Namen noch da.

Verwenden Sie ! von jetzt an bewusst. Eine Funktion, die nur erfolgreich sein kann, kann Result<T, !> zurückgeben, was RFC 1216 als motivierenden Anwendungsfall aufführt, und Aufrufer können allein auf den Ok-Arm matchen. Ein Handler, der niemals zurückkehrt, kann ohne Wrapper-Typ an generischen Code übergeben werden, der ein Fn() -> T erwartet, ein weiterer Anwendungsfall aus dem RFC. Lassen Sie das selbstgebaute enum Never {} fallen, sobald Ihre kleinste unterstützte Rust-Version es erlaubt.

Zehn Jahre sind eine lange Zeit für einen Typ aus einem Zeichen. Der zurückgenommene erste Versuch, die Einführung zuerst über die Edition und die crater-Zahl erklären das meiste davon. Sie sind auch der Grund, warum das eine Änderung ist, auf die Sie sich heute auf Nightly vorbereiten können, bevor sie Stable erreicht.

Quellen

  1. Never type - The Rust Reference - The Rust Reference
  2. Primitive type ! - Rust standard library documentation - Rust standard library docs
  3. RFC 1216: Promote ! to a type - Rust RFCs
  4. stabilize never type (PR #155499) - GitHub - rust-lang/rust
  5. Tracking issue for RFC 1216 (promoting ! to a type) - GitHub - rust-lang/rust
  6. Enum std::convert::Infallible - Rust standard library documentation - Rust standard library docs

Ähnliche Artikel