Rust estabiliza el tipo never: '!' deja de ser inestable tras dos años
El compilador de Rust ya acepta el tipo never '!' en código estable. El cambio arrastra una pequeña ruptura de compatibilidad que los mantenedores han tenido que medir contra el ecosistema.
Rust ha estabilizado el tipo never. Después de más de dos años de trabajo, el contribuidor conocido como waffle ha conseguido que el símbolo ! deje de ser una característica inestable y pase a estar disponible en el compilador estable, según el pull request correspondiente. El cambio no ha sido barato: arrastra una pequeña ruptura de compatibilidad con ediciones anteriores que los mantenedores han tenido que medir contra código real antes de dar el visto bueno.
Un tipo never es, literalmente, el tipo de lo que no ocurre. Lo devuelve una función que nunca retorna y marca los puntos donde un valor no puede existir. El compilador lo usaba desde hace tiempo en sus tripas, pero el lenguaje no lo exponía al programador. También es el tipo que le toca al resultado de un bucle infinito, algo que no sale todos los días en el código de producción, pero que simplifica la inferencia.
Una razón práctica y otra filosófica
La práctica es rendimiento en código genérico. En el trait FromStr de la biblioteca estándar, el tipo de error asociado puede ser ! cuando la conversión no puede fallar. Pasar una cadena a ByteString siempre funciona, así que Err se declara como never y el compilador sabe que la rama de error de ese Result jamás se va a ejecutar: la elimina. La interfaz genérica se mantiene igual, pero el código generado queda como el de una función que devuelve el valor directamente.
La filosófica tiene que ver con la inferencia de tipos. En Rust un if o un while son expresiones y su resultado se puede asignar a una variable, de modo que el compilador necesita deducir un tipo para lo que produce un bucle infinito. A esto se suma que el never se coercion implícitamente a cualquier otro tipo, lo que permite podar código muerto desde el propio sistema de tipos. Es una forma de eliminación de código guiada por el infierno de los tipos, nunca mejor dicho: si el programa afirma tener un valor de tipo never, esa rama es inalcanzable.
El escollo estaba en el llamado never fallback. Cuando el compilador no logra deducir el tipo concreto de una expresión —un closure que nunca retorna y que se invoca con el operador ? esperando un tipo de error concreto, por ejemplo— aplica una regla de reserva. Antes de la edición 2024 ese tipo era (), el tipo unitario. Con la edición 2024 pasó a ser !, lo que anula la conversión implícita. Es un cambio de comportamiento y, por tanto, técnicamente una ruptura: la inferencia de algunos fragmentos puede variar y provocar errores de compilación. Para eso existe el sistema de ediciones, que permite romper la parte frontal del lenguaje sin obligar a todo el ecosistema a migrar de golpe.
Con el never ya estable, la biblioteca estándar puede jubilar Infallible, el tipo que llevaba años haciendo de apaño porque el never no se podía tocar. Cumplía la misma función semántica pero sin soporte del compilador, así que el código era correcto y a la vez subóptimo: una capa extra de etiquetas en una enumeración o restos de código muerto que el optimizador no siempre conseguía eliminar. Estaba previsto que, llegada la estabilización, Infallible pase a ser un alias del tipo never. La documentación del tipo ya recoge el comportamiento estable.
Queda por ver cuánto código del ecosistema se apoya en la inferencia antigua y cuántos crates tendrán que anotar tipos que antes salían solos. Lo que cambia para quien escribe Rust es directo: ! se puede usar en estable sin nightly y sin recurrir a Infallible para marcar conversiones que no fallan.

