1 puntos por GN⁺ 4 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Rust 1.96.0 se puede instalar con rustup update stable, y la verificación de futuras versiones estará abierta en los canales beta/nightly
  • Los nuevos tipos core::range::Range* implementan IntoIterator en vez de Iterator, lo que permite implementar Copy, y en el futuro serán los tipos base de la sintaxis de rangos
  • assert_matches! y debug_assert_matches! ahora muestran también la representación Debug del valor cuando el patrón no coincide, facilitando el diagnóstico de fallas en pruebas
  • Los targets de WebAssembly ya no pasan --allow-undefined por defecto, así que los símbolos no definidos ahora provocan un error del linker en lugar de convertirse en imports
  • Cargo incluye correcciones para CVE-2026-5223 y CVE-2026-5222 para usuarios de registros de terceros, y los usuarios de crates.io no se ven afectados

Cambios principales de Rust 1.96.0

  • Actualización y canales de prueba

    • Los usuarios que ya tengan Rust instalado con rustup pueden obtener Rust 1.96.0 con rustup update stable
    • Si no tienes rustup, puedes instalarlo desde la página de instalación de rustup del sitio web de Rust, y también ya están publicadas las notas detalladas de la versión 1.96.0
    • Si quieres participar en la verificación de futuras versiones, puedes usar los canales beta/nightly con rustup default beta o rustup default nightly, y reportar bugs en el issue tracker de Rust
  • Nuevos tipos Range*

    • Muchos usuarios esperaban que Range y los tipos relacionados de core::ops implementaran Copy, pero no lo hacían porque implementan Iterator directamente
    • Implementar Iterator y Copy a la vez en el mismo tipo es un footgun que Clippy señala, por eso se había evitado
    • RFC3550 propuso tipos alternativos de rango que implementan IntoIterator en vez de Iterator, y con esa estructura esos tipos también pueden implementar Copy
    • En la librería estándar se estabilizaron core::range::Range, core::range::RangeFrom, core::range::RangeInclusive y sus iteradores relacionados
    • En una versión cercana de Rust también se agregarán core::range::RangeFull y core::range::RangeTo, reexportados desde core::ops, además de core::range::legacy::*, que será la nueva ubicación de los tipos de rango actuales
    • La sintaxis de rangos como 0..1 hoy crea tipos legacy, pero en una futura edición cambiará a los tipos de core::range
    • Con esta nueva estabilización, ahora se pueden guardar accesores de slices en tipos Copy sin tener que separar start y end
    • Ejemplo:
      use core::range::Range;
      
      #[derive(Clone, Copy)]
      pub struct Span(Range<usize>);
      
      impl Span {
          pub fn of(self, s: &str) -> &str {
              &s[self.0]
          }
      }
      
    • El nuevo RangeInclusive hace públicos sus campos, ya que ya no necesita evitar exponer el estado de un iterador consumido como ocurría con la versión legacy
    • Como los nuevos tipos primero deben convertirse antes de comenzar a iterarse, los campos públicos no representan un problema
    • Se recomienda a los autores de librerías considerar el uso de impl RangeBounds en APIs públicas para aceptar tanto los tipos de rango legacy como los nuevos
    • Si se necesita un tipo concreto, se recomienda preferir los nuevos tipos de rango, que serán el valor por defecto en el futuro
  • Macros de aserción para pattern matching

    • Las nuevas macros assert_matches! y debug_assert_matches! verifican si un valor coincide con un patrón dado y, si no coincide, hacen panic junto con la representación Debug de ese valor
    • En esencia son equivalentes a assert!(matches!(..)) y debug_assert!(matches!(..)), pero mejoran la capacidad de diagnóstico gracias al valor que se imprime cuando fallan
    • No se agregaron al preludio estándar porque podrían entrar en conflicto con crates populares de terceros que ya ofrecen macros con el mismo nombre
    • Antes de usarlas hay que importarlas directamente desde core o std
    • Ejemplo:
      use core::assert_matches;
      
      /// [Random Number](https://xkcd.com/221/)
      fn get_random_number() -> u32 {
          // chosen by a fair dice roll.
          // guaranteed to be random.
          4
      }
      
      fn main() {
          assert_matches!(get_random_number(), 1..=6);
      }
      
  • Cambio en los targets de WebAssembly

    • Los targets de WebAssembly ya no pasan --allow-undefined al linker
    • Durante el enlace, los símbolos no definidos ya no se convierten en imports de WebAssembly del módulo "env", sino que ahora generan un error del linker
    • Si todos los símbolos relacionados con el enlace deben estar definidos para que el módulo enlace, se pueden detectar bugs antes y evitar problemas accidentales causados, por ejemplo, por nombres de símbolos
    • Los símbolos no definidos relacionados con el enlace suelen indicar bugs en tiempo de compilación o errores de configuración
    • Si el comportamiento anterior era intencional, se puede restaurar con RUSTFLAGS=-Clink-arg=--allow-undefined, o usar #[link(wasm_import_module = "env")] en el bloque donde se define el símbolo en el código fuente
    • Este cambio se aplica en Rust 1.96 después del anuncio previo en el blog

APIs estabilizadas y correcciones de seguridad

1 comentarios

 
GN⁺ 4 시간 전
Opiniones en Lobste.rs
  • assert_matches es de esas cosas que siempre termino queriendo tener, y cada vez me hace dudar entre agregar otro crate o volver a implementarlo yo mismo
    Así que me alegra que entre en la biblioteca estándar

    • ¿Es raro emocionarse por poder borrar cientos de pares de paréntesis en los tests? Yo diría que no, para nada
  • Me gusta el paso hacia hacer que los rangos sean de tipo Copy
    A veces me ha sorprendido tener que clonar rangos, y también encaja mejor con la intuición de que 12..34 debería ser un dato pequeño y copiable
    Eso sí, si empiezan a existir varios tipos con el mismo nombre, me preocupa un poco que VS Code termine importando el tipo equivocado la próxima vez que agregue automáticamente una declaración use

    A Rust version in the near future will also add [...] core::range::legacy::* as the new home for the current ranges. Range syntax like 0..1 still produces the legacy types for now, but will be updated to core::range types in a future edition.
    El sistema de ediciones de Rust parece una idea bastante buena

    • Hasta donde sé, si hay ambigüedad en una importación, la acción de código de VS Code debería abrir un menú desplegable para elegir cuál usar
    • Tampoco parece que sea necesario importar este tipo de tipos muy seguido
      Para la mayoría de los usuarios, la ventaja de los tipos nuevos es pequeña, así que pueden seguir usando los tipos existentes, y en el siguiente cambio de edición los tipos nuevos pasarán a usarse automáticamente
      Me imagino que quienes más van a importar estos tipos serán los autores de bibliotecas que quieran dar soporte explícito a ambas versiones
  • These new macros have not been added to the standard prelude, because they would collide with popular third-party crates that provide macros with the same name. Instead, they should be manually imported from core or std before use.
    Esto se siente un poco raro
    ¿Habrá planes de cambiarlo más adelante? Parece el tipo de cosa que uno querría convertir en una pequeña limpieza después de que el ecosistema se haya movido, digamos, en unos 3 años

    • Las ediciones ayudan justo en este tipo de cosas
      Puedes cambiar el preludio sin romper los proyectos existentes