Rust Edición 2024: lo que cambia de verdad en el día a día
Actualizado: 2026-05-03
La Edición 2024 de Rust salió estable el 20 de febrero junto a Rust 1.85, y siete semanas después ya hay datos suficientes para hablar de lo que aporta en la práctica. Las ediciones en Rust son un mecanismo curioso: no rompen la compatibilidad, pero permiten cambiar defaults que de otro modo romperían código existente. Un crate con edition = "2024" compila contra el mismo compilador que uno con edition = "2021", y los dos pueden depender el uno del otro. Lo que cambia es la manera en que se escribe nuevo código y algunos comportamientos que ajustan detalles del lenguaje.
Este post es un análisis práctico de los cambios que más afectan al trabajo diario, con énfasis en lo que realmente importa para quien ya usa Rust. Para el contexto del rol de Rust en sistemas más allá de userspace, el análisis de Rust en el kernel de Linux ilustra el camino de madurez del lenguaje.
Puntos clave
- La migración con
cargo fix --editiones la vía recomendada; resuelve la mayoría de cambios automáticamente. - Captura granular en cierres (
use<T>en Return Position Impl Trait) elimina capturas innecesarias de por vida. - El prelude de 2024 añade
Future,IntoFuture,AsyncFn*,LazyCellyLazyLock. unsafeen bloquesexternes ahora obligatorio;cargo fixmigra automáticamente.- Los cierres en
async fnya no requieren move explícito en la mayoría de casos.
Cómo funcionan las ediciones en Rust
Las ediciones son Rust’s way de evolucionar el lenguaje sin quebrar código existente. Rust 1.0 introdujo la promesa de estabilidad: código que compila hoy seguirá compilando en futuras versiones. Las ediciones son la válvula de escape para cambios que requerirían romper esa promesa si se aplicaran globalmente.
Cuando un crate declara edition = "2024" en Cargo.toml, opta por el conjunto de semánticas de esa edición. Los crates con edition = "2021" en el mismo workspace siguen compilando con las semánticas anteriores. El compilador conoce la edición de cada crate y aplica las reglas correspondientes. Nunca hay ruptura cross-crate: un crate 2024 puede depender de un crate 2021 y viceversa.
La migración entre ediciones es asistida por cargo fix --edition, que reescribe automáticamente el código que necesita cambiar. La mayoría de proyectos reales migran de 2021 a 2024 con este comando y sin intervención manual significativa, salvo en casos con patrones inusuales de captura de closures o bloques extern complejos.
Captura granular en cierres: el cambio más relevante
El cambio que más impacto tiene en código real es el refinamiento de la captura de variables en closures y en Return Position Impl Trait (RPIT).
En Rust 2021, cuando un cierre capturaba algo que implementaba Future, a veces capturaba más de lo necesario, forzando tiempos de vida más restrictivos de lo que el programador quería. En 2024, la captura es más granular: el compilador captura exactamente lo que se usa, no el objeto completo si solo se necesita un campo.
La consecuencia práctica es que código async que en 2021 requería workarounds para satisfacer el borrow checker (como mover datos explícitamente antes de la llamada async, o usar Arc donde no era semánticamente necesario) en 2024 simplemente funciona. El número de casos donde async move {} era obligatorio baja significativamente.
El complemento de esto es la sintaxis use<T> en RPIT, que permite declarar explícitamente qué lifetimes y tipos genéricos captura un tipo de retorno opaco. Esto elimina ambigüedad del compilador sobre qué se captura, lo cual era una fuente frecuente de errores difíciles de depurar en código con géneros y tiempos de vida entrelazados.
El prelude ampliado de 2024
El prelude es el conjunto de nombres que Rust importa automáticamente en cada módulo sin necesidad de use explícito. En 2024 se añaden varios tipos y traits relacionados con async:
FutureyIntoFuture.AsyncFn,AsyncFnMut,AsyncFnOnce.LazyCellyLazyLock(inicialización perezosa thread-safe).
El impacto más inmediato es que código async ya no necesita importar Future explícitamente en cada archivo donde se trabaja con él. LazyCell y LazyLock disponibles en prelude reducen el boilerplate de la inicialización perezosa, que era un patrón frecuente pero verboso con once_cell externo.
Hay un matiz importante: si un proyecto tenía identificadores con esos mismos nombres, la adición al prelude puede causar colisiones de nombres que cargo fix no siempre resuelve automáticamente. El escenario es raro pero vale la pena verificar.
unsafe más explícito en bloques extern
En Rust 2024, los bloques extern "C" {} requieren la palabra clave unsafe explícitamente:
// Rust 2021:
extern "C" {
fn puts(s: *const u8) -> i32;
}
// Rust 2024:
unsafe extern "C" {
fn puts(s: *const u8) -> i32;
}El cambio refuerza la señalización de que las declaraciones en extern implican código externo al control del borrow checker de Rust. cargo fix --edition migra esto automáticamente, por lo que en la práctica no requiere trabajo manual en la mayoría de proyectos.
Hay una contraparte útil: las funciones dentro de bloques unsafe extern que el programador puede garantizar que son seguras de llamar se pueden marcar con safe:
unsafe extern "C" {
safe fn abs(input: i32) -> i32; // se puede llamar sin unsafe
unsafe fn gets(s: *mut u8); // sigue requiriendo unsafe en la llamada
}Esto mejora la ergonomía de las FFI bindings sin perder la señal de qué es verdaderamente inseguro.
Migración en la práctica
El proceso de migración para un proyecto real:
- Actualizar la toolchain a 1.85 o superior:
rustup update stable. - Ejecutar
cargo fix --editionen el workspace. - Cambiar
edition = "2024"en losCargo.tomlafectados. - Ejecutar
cargo testycargo clippyy atender los avisos. - Revisar manualmente los casos que
cargo fixno haya podido migrar automáticamente.
En proyectos con mucho código FFI o con patrones inusuales de closures, el paso 5 puede requerir algunas horas. En proyectos típicos de aplicación o biblioteca sin FFI, la migración suele completarse en menos de treinta minutos.
Mi lectura
La Edición 2024 de Rust es una edición de ergonomía, no de titulares. No hay nuevas features espectaculares; hay refinamientos que eliminan fricción real en patrones de código habituales. La captura granular en closures y el prelude async son los cambios que más se van a agradecer en el trabajo diario con código async, que es la mitad del Rust que se escribe hoy.
La migración es tan sencilla que no hay razón para no hacerla en proyectos activos que ya usen edición 2021. El riesgo es bajo, la herramienta hace la mayor parte del trabajo y los beneficios son inmediatos. El único freno real es si el proyecto mantiene compatibilidad con versiones de Rust anteriores a 1.85, en cuyo caso hay que esperar o hacer la migración condicionada.