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.
This commit is contained in:
parent
e9b7aa08f7
commit
5d8f9b4dc1
18 changed files with 172 additions and 57 deletions
|
@ -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}"))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue