El equipo de Rust se complace en anunciar una nueva versión de Rust, 1.78.0. Rust es un lenguaje de programación que permite a todos construir software confiable y eficiente.
\ Si tienes una versión anterior de Rust instalada a través de rustup, puedes obtener 1.78.0 con:
$ rustup update stable
\ Si aún no lo tienes, puedes obtener rustup desde la página correspondiente en nuestro sitio web, y consultar las notas detalladas de la versión 1.78.0.
\ Si deseas ayudarnos probando futuras versiones, podrías considerar actualizar localmente para usar el canal beta (rustup default beta) o el canal nightly (rustup default nightly). ¡Por favor, reporta cualquier error que puedas encontrar!
Rust ahora admite un espacio de nombres de atributo #[diagnostic] para influir en los mensajes de error del compilador. Estos son tratados como sugerencias que el compilador no está obligado a usar, y tampoco es un error proporcionar un diagnóstico que el compilador no reconozca. Esta flexibilidad permite que el código fuente proporcione diagnósticos incluso cuando no son compatibles con todos los compiladores, ya sean versiones diferentes o implementaciones completamente diferentes.
\ Con este espacio de nombres llega el primer atributo compatible, #[diagnostic::on_unimplemented], que se puede colocar en un trait para personalizar el mensaje cuando ese trait es requerido pero no ha sido implementado en un tipo. Considera el ejemplo dado en la solicitud de estabilización:
#[diagnostic::on_unimplemented( message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`", label = "My Label", note = "Note 1", note = "Note 2" )] trait ImportantTrait<A> {} fn use_my_trait(_: impl ImportantTrait<i32>) {} fn main() { use_my_trait(String::new()); }
\ Anteriormente, el compilador daría un error integrado como este:
error[E0277]: the trait bound `String: ImportantTrait<i32>` is not satisfied --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ the trait `ImportantTrait<i32>` is not implemented for `String` | | | required by a bound introduced by this call |
\ Con #[diagnostic::on_unimplemented], su mensaje personalizado llena la línea de error principal, y su etiqueta personalizada se coloca en la salida del código fuente. La etiqueta original todavía se escribe como salida de ayuda, y cualquier nota personalizada también se escribe. (Estos detalles exactos están sujetos a cambios.)
error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String` --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait<i32>` is not implemented for `String` = note: Note 1 = note: Note 2
\ Para los autores de traits, este tipo de diagnóstico es más útil si puedes proporcionar una mejor pista que solo hablar sobre la implementación faltante en sí. Por ejemplo, esta es una muestra abreviada de la biblioteca estándar:
#[diagnostic::on_unimplemented( message = "the size for values of type `{Self}` cannot be known at compilation time", label = "doesn't have a size known at compile-time" )] pub trait Sized {}
\ Para más información, consulta la sección de referencia sobre el espacio de nombres de atributos de herramientas diagnostic.
unsafeLa biblioteca estándar de Rust tiene una serie de afirmaciones para las precondiciones de funciones unsafe, pero históricamente solo se han habilitado en compilaciones #[cfg(debug_assertions)] de la biblioteca estándar para evitar afectar el rendimiento de la versión de lanzamiento. Sin embargo, dado que la biblioteca estándar generalmente se compila y distribuye en modo de lanzamiento, la mayoría de los desarrolladores de Rust nunca ejecutaban estas comprobaciones.
\ Ahora, la condición para estas afirmaciones se retrasa hasta la generación de código, por lo que se verificarán dependiendo de la configuración propia del usuario para las afirmaciones de depuración -- habilitadas por defecto en compilaciones de depuración y prueba. Este cambio ayuda a los usuarios a detectar comportamientos indefinidos en su código, aunque los detalles de cuánto se verifica generalmente no son estables.
\ Por ejemplo, slice::from_raw_parts requiere un puntero no nulo alineado. El siguiente uso de un puntero intencionalmente desalineado tiene un comportamiento indefinido, y aunque si tuvieras mala suerte podría haber parecido "funcionar" en el pasado, la afirmación de depuración ahora puede detectarlo:
fn main() { let slice: &[u8] = &[1, 2, 3, 4, 5]; let ptr = slice.as_ptr(); // Create an offset from `ptr` that will always be one off from `u16`'s correct alignment let i = usize::from(ptr as usize & 1 == 0); let slice16: &[u16] = unsafe { std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 2) }; dbg!(slice16); } thread 'main' panicked at library/core/src/panicking.rs:220:5: unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX` note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread caused non-unwinding panic. aborting.
La biblioteca estándar tiene algunas funciones que cambian la alineación de punteros y slices, pero anteriormente tenían advertencias que las hacían difíciles de usar en la práctica, si seguías su documentación con precisión. Esas advertencias existían principalmente como protección contra la evaluación const, pero de todos modos solo son estables para uso no const. Ahora se promete que tendrán un comportamiento de tiempo de ejecución consistente según sus entradas reales.
pointer::align_offset calcula el desplazamiento necesario para cambiar un puntero a la alineación dada. Devuelve usize::MAX si eso no es posible, pero anteriormente se permitía siempre devolver usize::MAX, y ahora ese comportamiento se elimina.slice::align_to y slice::align_to_mut ambos transmutan slices a un slice medio alineado y los slices de cabeza y cola no alineados restantes. Estos métodos ahora prometen devolver la parte media más grande posible, en lugar de permitir que la implementación devuelva algo menos óptimo como devolver todo como el slice de cabeza.impl Read for &Stdin'static para varias implementaciones relacionadas con std::error::Errorimpl<Fd: AsFd> impl tome ?Sizedimpl From<TryReserveError> for io::Error\ Estas APIs ahora son estables en contextos const:
Barrier::new()x86_64-pc-windows-msvci686-pc-windows-msvcx86_64-pc-windows-gnui686-pc-windows-gnux86_64-pc-windows-gnullvmi686-pc-windows-gnullvmu128/i128 anunciado para objetivos x86-32 y x86-64. Los distribuidores que usan su propio LLVM anterior a 18 pueden seguir enfrentando los errores de convención de llamada mencionados en esa publicación.Consulta todo lo que cambió en Rust, Cargo y Clippy.
Muchas personas se unieron para crear Rust 1.78.0. No podríamos haberlo hecho sin todos ustedes. ¡Gracias!
El Equipo de Lanzamiento de Rust
\ También publicado aquí
\ Foto de Ubaid E. Alyafizi en Unsplash


