Después de una década de desarrollo y cinco intentos fallidos de estabilización, el equipo de Rust ha estabilizado oficialmente el tipo 'never' (!) en la versión 1.100.0. Este cambio permite a los desarrolladores representar explícitamente computaciones divergentes —código que nunca resuelve en un valor, como una función que siempre devuelve o sale—, permitiendo una comprobación de tipos más expresiva en flujos de control complejos como las ramas de `match`.

La estabilización del tipo 'Never'

El tipo 'never', denotado por el símbolo `!`, representa computaciones que nunca resuelven en un valor. Aunque anteriormente era utilizable en ciertos contextos, este lanzamiento permite que sea nombrado en cualquier lugar, incluso como un parámetro genérico o un tipo de retorno.

Una característica clave del tipo 'never' es su capacidad para coercerse en cualquier otro tipo. Esto permite que una rama de `match` que realiza un `return` supere la comprobación de tipos incluso si las otras ramas devuelven un valor específico, ya que el compilador trata el `return` como una transición válida al tipo esperado.

Fragmento de código Rust que demuestra el símbolo del tipo never
Un ejemplo de código que ilustra cómo se utiliza el tipo 'never' (!) en Rust.blog.rust-lang.org

Esta captura de pantalla proporciona un ejemplo de código concreto del tipo 'never' recién estabilizado y su comportamiento en el lenguaje.

Para soportar esto, el equipo cambió el 'fallback del tipo never' de `()` a `!` para las ediciones anteriores a 2024. Aunque esto es mayormente imperceptible, puede causar que el compilador detecte más código inalcanzable o afecte a casos raros que involucran parámetros genéricos.

Asignadores personalizados y gestión de memoria

Rust 1.100.0 marca un hito importante para el proyecto Allocators 1.0 al estabilizar el trait central `Allocator`. Esto permite a los autores de librerías definir estrategias de asignación de memoria personalizadas que pueden usarse directamente con tipos de la biblioteca estándar como `Vec` y `Box`.

Aspectos destacados de Rust 1.100.0: Objetivos del proyecto estabilizado 3; Nuevos tipos de ayuda 1
Aspectos destacados de Rust 1.100.0blog.rust-lang.org

Gráfico elaborado por HN Digest a partir de cifras de blog.rust-lang.org; los valores se muestran como en la fuente.

Si bien esto proporciona la base para la gestión de memoria personalizada, el equipo señala que aún queda más trabajo por hacer para expandir la superficie de la API y estabilizar estos asignadores para una gama más amplia de colecciones y tipos de punteros.

Seguridad de la cadena de suministro y mejoras en Cargo

Para protegerse contra lanzamientos de paquetes maliciosos, Cargo ahora admite 'dependency cooldowns' a través de la configuración `global-min-publish-age`. Esto permite a los usuarios especificar una edad mínima (por ejemplo, 3 días) antes de que Cargo resuelva una versión recién publicada de una dependencia.

Configuración de Cargo para los tiempos de espera de dependencias
Ejemplo de la configuración de Cargo utilizada para implementar los tiempos de espera de dependencias.blog.rust-lang.org

Esta imagen muestra la sintaxis de configuración para la función de 'dependency cooldowns' mencionada en la sección de seguridad de la cadena de suministro.

El lanzamiento también introduce informes automatizados para dependencias no utilizadas en `Cargo.toml`. Esto ayuda a los desarrolladores a mantener sus configuraciones de compilación ligeras al advertirles sobre los crates que se incluyen en el espacio de trabajo pero que no son utilizados por ningún objetivo de compilación.

Adicionalmente, la estructura del directorio de compilación de Cargo fue renovada para aplicar consistentemente los hashes de configuración de compilación. Este cambio tiene como objetivo reducir las reconstrucciones adicionales y resolver problemas donde diferentes configuraciones compartían archivos de una manera que causaba colisiones de caché.

Nuevas herramientas: DropGuard y conjuración de ZSTs

El nuevo tipo de ayuda `core::mem::DropGuard` simplifica la creación de APIs de 'todo o nada'. Toma una variable y un closure, ejecutando el closure solo cuando el guardián es descartado, mientras proporciona un método `dismiss` para devolver la variable sin activar el destructor.

Ejemplo de implementación de DropGuard en Rust
Una lista de código que demuestra el uso del nuevo tipo de ayuda DropGuard.blog.rust-lang.org

Esta captura de pantalla ilustra el tipo de ayuda DropGuard, que simplifica las APIs de tipo transacción de 'todo o nada'.

Para la programación de sistemas de bajo nivel, el lanzamiento añade `std::mem::conjure_zst`. Esto proporciona una forma dedicada e insegura de crear tipos de tamaño cero (ZSTs) cuando el desarrollador sabe que la operación es segura, reemplazando varias 'incantaciones' como transmutar `()` o usar `MaybeUninit`.

Qué dicen los lectores de Hacker News

  • Experiencia: Un comentarista compartió que recientemente tuvo que usar la API de asignador para solucionar fugas de memoria en una librería específica, señalando que estas funciones ya están disponibles en la versión estable. comentario ↗
  • Experiencia: Un usuario informó que actualizar a la nueva versión durante una sesión de codificación asistida por IA permitió a la herramienta identificar y eliminar con éxito varias dependencias no utilizadas. comentario ↗
  • Escéptico: Un lector expresó su frustración con respecto a los tiempos de compilación lentos y la gran cantidad de archivos temporales generados durante el proceso de compilación. comentario ↗
  • Pregunta abierta: Un comentarista cuestionó por qué ciertas funciones esperadas no se incluyeron en el lanzamiento junto con la estabilización del tipo 'never' comentario ↗

Resumen de opiniones del hilo de Hacker News; no son hechos verificados. Leer el debate completo ↗