about summary refs log tree commit diff
path: root/library/std/src/env.rs
diff options
context:
space:
mode:
authorTobias Bucher <tobiasbucher5991@gmail.com>2024-05-13 09:05:34 +0200
committerTobias Bucher <tobiasbucher5991@gmail.com>2024-05-29 23:42:27 +0200
commit5d8f9b4dc1c913e62387e10762f018f182a34582 (patch)
treef7e5123f4aaf7c6e4cc1ce7fa9d8c087ce891b46 /library/std/src/env.rs
parente9b7aa08f7cd890dcebd36c198193707d5cd3770 (diff)
downloadrust-5d8f9b4dc1c913e62387e10762f018f182a34582.tar.gz
rust-5d8f9b4dc1c913e62387e10762f018f182a34582.zip
Make `std::env::{set_var, remove_var}` unsafe in edition 2024
Allow calling these functions without `unsafe` blocks in editions up
until 2021, but don't trigger the `unused_unsafe` lint for `unsafe`
blocks containing these functions.

Fixes #27970.
Fixes #90308.
CC #124866.
Diffstat (limited to 'library/std/src/env.rs')
-rw-r--r--library/std/src/env.rs54
1 files changed, 34 insertions, 20 deletions
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 6f8ac17f12c..95ee2a91d15 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -318,11 +318,6 @@ impl Error for VarError {
 ///
 /// # Safety
 ///
-/// Even though this function is currently not marked as `unsafe`, it needs to
-/// be because invoking it can cause undefined behaviour. The function will be
-/// marked `unsafe` in a future version of Rust. This is tracked in
-/// [rust#27970](https://github.com/rust-lang/rust/issues/27970).
-///
 /// This function is safe to call in a single-threaded program.
 ///
 /// In multi-threaded programs, you must ensure that are no other threads
@@ -331,7 +326,7 @@ impl Error for VarError {
 /// how to achieve this, but we strongly suggest not using `set_var` or
 /// `remove_var` in multi-threaded programs at all.
 ///
-/// Most C libraries, including libc itself do not advertise which functions
+/// Most C libraries, including libc itself, do not advertise which functions
 /// read from the environment. Even functions from the Rust standard library do
 /// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`].
 ///
@@ -353,15 +348,26 @@ impl Error for VarError {
 /// use std::env;
 ///
 /// let key = "KEY";
-/// env::set_var(key, "VALUE");
+/// unsafe {
+///     env::set_var(key, "VALUE");
+/// }
 /// assert_eq!(env::var(key), Ok("VALUE".to_string()));
 /// ```
+#[cfg(not(bootstrap))]
+#[rustc_deprecated_safe_2024]
 #[stable(feature = "env", since = "1.0.0")]
-pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
+pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
     _set_var(key.as_ref(), value.as_ref())
 }
 
-fn _set_var(key: &OsStr, value: &OsStr) {
+#[cfg(bootstrap)]
+#[allow(missing_docs)]
+#[stable(feature = "env", since = "1.0.0")]
+pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
+    unsafe { _set_var(key.as_ref(), value.as_ref()) }
+}
+
+unsafe fn _set_var(key: &OsStr, value: &OsStr) {
     os_imp::setenv(key, value).unwrap_or_else(|e| {
         panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}")
     })
@@ -371,11 +377,6 @@ fn _set_var(key: &OsStr, value: &OsStr) {
 ///
 /// # Safety
 ///
-/// Even though this function is currently not marked as `unsafe`, it needs to
-/// be because invoking it can cause undefined behaviour. The function will be
-/// marked `unsafe` in a future version of Rust. This is tracked in
-/// [rust#27970](https://github.com/rust-lang/rust/issues/27970).
-///
 /// This function is safe to call in a single-threaded program.
 ///
 /// In multi-threaded programs, you must ensure that are no other threads
@@ -384,7 +385,7 @@ fn _set_var(key: &OsStr, value: &OsStr) {
 /// how to achieve this, but we strongly suggest not using `set_var` or
 /// `remove_var` in multi-threaded programs at all.
 ///
-/// Most C libraries, including libc itself do not advertise which functions
+/// Most C libraries, including libc itself, do not advertise which functions
 /// read from the environment. Even functions from the Rust standard library do
 /// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`].
 ///
@@ -403,22 +404,35 @@ fn _set_var(key: &OsStr, value: &OsStr) {
 ///
 /// # Examples
 ///
-/// ```
+/// ```no_run
 /// use std::env;
 ///
 /// let key = "KEY";
-/// env::set_var(key, "VALUE");
+/// unsafe {
+///     env::set_var(key, "VALUE");
+/// }
 /// assert_eq!(env::var(key), Ok("VALUE".to_string()));
 ///
-/// env::remove_var(key);
+/// unsafe {
+///     env::remove_var(key);
+/// }
 /// assert!(env::var(key).is_err());
 /// ```
+#[cfg(not(bootstrap))]
+#[rustc_deprecated_safe_2024]
 #[stable(feature = "env", since = "1.0.0")]
-pub fn remove_var<K: AsRef<OsStr>>(key: K) {
+pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
     _remove_var(key.as_ref())
 }
 
-fn _remove_var(key: &OsStr) {
+#[cfg(bootstrap)]
+#[allow(missing_docs)]
+#[stable(feature = "env", since = "1.0.0")]
+pub fn remove_var<K: AsRef<OsStr>>(key: K) {
+    unsafe { _remove_var(key.as_ref()) }
+}
+
+unsafe fn _remove_var(key: &OsStr) {
     os_imp::unsetenv(key)
         .unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}"))
 }