Skip to content

Commit 0cc7fb1

Browse files
committed
Auto merge of rust-lang#140282 - matthiaskrgr:rollup-g6ze4jj, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#137653 (Deprecate the unstable `concat_idents!`) - rust-lang#138957 (Update the index of Option to make the summary more comprehensive) - rust-lang#140006 (ensure compiler existance of tools on the dist step) - rust-lang#140143 (Move `sys::pal::os::Env` into `sys::env`) - rust-lang#140202 (Make #![feature(let_chains)] bootstrap conditional in compiler/) - rust-lang#140236 (norm nested aliases before evaluating the parent goal) - rust-lang#140257 (Some drive-by housecleaning in `rustc_borrowck`) - rust-lang#140278 (Don't use item name to look up associated item from trait item) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6f7c25d + 1eb4c4c commit 0cc7fb1

File tree

39 files changed

+996
-1220
lines changed

39 files changed

+996
-1220
lines changed

core/src/macros/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,10 @@ pub(crate) mod builtin {
11381138
issue = "29599",
11391139
reason = "`concat_idents` is not stable enough for use and is subject to change"
11401140
)]
1141+
#[deprecated(
1142+
since = "1.88.0",
1143+
note = "use `${concat(...)}` with the `macro_metavar_expr_concat` feature instead"
1144+
)]
11411145
#[rustc_builtin_macro]
11421146
#[macro_export]
11431147
macro_rules! concat_idents {

core/src/option.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,14 @@
162162
//! The [`is_some`] and [`is_none`] methods return [`true`] if the [`Option`]
163163
//! is [`Some`] or [`None`], respectively.
164164
//!
165+
//! The [`is_some_and`] and [`is_none_or`] methods apply the provided function
166+
//! to the contents of the [`Option`] to produce a boolean value.
167+
//! If this is [`None`] then a default result is returned instead without executing the function.
168+
//!
165169
//! [`is_none`]: Option::is_none
166170
//! [`is_some`]: Option::is_some
171+
//! [`is_some_and`]: Option::is_some_and
172+
//! [`is_none_or`]: Option::is_none_or
167173
//!
168174
//! ## Adapters for working with references
169175
//!
@@ -177,6 +183,10 @@
177183
//! <code>[Option]<[Pin]<[&]T>></code>
178184
//! * [`as_pin_mut`] converts from <code>[Pin]<[&mut] [Option]\<T>></code> to
179185
//! <code>[Option]<[Pin]<[&mut] T>></code>
186+
//! * [`as_slice`] returns a one-element slice of the contained value, if any.
187+
//! If this is [`None`], an empty slice is returned.
188+
//! * [`as_mut_slice`] returns a mutable one-element slice of the contained value, if any.
189+
//! If this is [`None`], an empty slice is returned.
180190
//!
181191
//! [&]: reference "shared reference"
182192
//! [&mut]: reference "mutable reference"
@@ -187,6 +197,8 @@
187197
//! [`as_pin_mut`]: Option::as_pin_mut
188198
//! [`as_pin_ref`]: Option::as_pin_ref
189199
//! [`as_ref`]: Option::as_ref
200+
//! [`as_slice`]: Option::as_slice
201+
//! [`as_mut_slice`]: Option::as_mut_slice
190202
//!
191203
//! ## Extracting the contained value
192204
//!
@@ -200,12 +212,15 @@
200212
//! (which must implement the [`Default`] trait)
201213
//! * [`unwrap_or_else`] returns the result of evaluating the provided
202214
//! function
215+
//! * [`unwrap_unchecked`] produces *[undefined behavior]*
203216
//!
204217
//! [`expect`]: Option::expect
205218
//! [`unwrap`]: Option::unwrap
206219
//! [`unwrap_or`]: Option::unwrap_or
207220
//! [`unwrap_or_default`]: Option::unwrap_or_default
208221
//! [`unwrap_or_else`]: Option::unwrap_or_else
222+
//! [`unwrap_unchecked`]: Option::unwrap_unchecked
223+
//! [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
209224
//!
210225
//! ## Transforming contained values
211226
//!
@@ -230,15 +245,17 @@
230245
//! * [`filter`] calls the provided predicate function on the contained
231246
//! value `t` if the [`Option`] is [`Some(t)`], and returns [`Some(t)`]
232247
//! if the function returns `true`; otherwise, returns [`None`]
233-
//! * [`flatten`] removes one level of nesting from an
234-
//! [`Option<Option<T>>`]
248+
//! * [`flatten`] removes one level of nesting from an [`Option<Option<T>>`]
249+
//! * [`inspect`] method takes ownership of the [`Option`] and applies
250+
//! the provided function to the contained value by reference if [`Some`]
235251
//! * [`map`] transforms [`Option<T>`] to [`Option<U>`] by applying the
236252
//! provided function to the contained value of [`Some`] and leaving
237253
//! [`None`] values unchanged
238254
//!
239255
//! [`Some(t)`]: Some
240256
//! [`filter`]: Option::filter
241257
//! [`flatten`]: Option::flatten
258+
//! [`inspect`]: Option::inspect
242259
//! [`map`]: Option::map
243260
//!
244261
//! These methods transform [`Option<T>`] to a value of a possibly
@@ -621,6 +638,10 @@ impl<T> Option<T> {
621638
///
622639
/// let x: Option<u32> = None;
623640
/// assert_eq!(x.is_some_and(|x| x > 1), false);
641+
///
642+
/// let x: Option<String> = Some("ownership".to_string());
643+
/// assert_eq!(x.as_ref().is_some_and(|x| x.len() > 1), true);
644+
/// println!("still alive {:?}", x);
624645
/// ```
625646
#[must_use]
626647
#[inline]
@@ -665,6 +686,10 @@ impl<T> Option<T> {
665686
///
666687
/// let x: Option<u32> = None;
667688
/// assert_eq!(x.is_none_or(|x| x > 1), true);
689+
///
690+
/// let x: Option<String> = Some("ownership".to_string());
691+
/// assert_eq!(x.as_ref().is_none_or(|x| x.len() > 1), true);
692+
/// println!("still alive {:?}", x);
668693
/// ```
669694
#[must_use]
670695
#[inline]

core/src/prelude/v1.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub use crate::hash::macros::Hash;
5959

6060
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
6161
#[allow(deprecated)]
62+
#[cfg_attr(bootstrap, allow(deprecated_in_future))]
6263
#[doc(no_inline)]
6364
pub use crate::{
6465
assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,

std/src/env.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use crate::error::Error;
1414
use crate::ffi::{OsStr, OsString};
1515
use crate::path::{Path, PathBuf};
16-
use crate::sys::os as os_imp;
16+
use crate::sys::{env as env_imp, os as os_imp};
1717
use crate::{fmt, io, sys};
1818

1919
/// Returns the current working directory as a [`PathBuf`].
@@ -96,7 +96,7 @@ pub struct Vars {
9696
/// [`env::vars_os()`]: vars_os
9797
#[stable(feature = "env", since = "1.0.0")]
9898
pub struct VarsOs {
99-
inner: os_imp::Env,
99+
inner: env_imp::Env,
100100
}
101101

102102
/// Returns an iterator of (variable, value) pairs of strings, for all the
@@ -150,7 +150,7 @@ pub fn vars() -> Vars {
150150
#[must_use]
151151
#[stable(feature = "env", since = "1.0.0")]
152152
pub fn vars_os() -> VarsOs {
153-
VarsOs { inner: os_imp::env() }
153+
VarsOs { inner: env_imp::env() }
154154
}
155155

156156
#[stable(feature = "env", since = "1.0.0")]
@@ -259,7 +259,7 @@ pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
259259
}
260260

261261
fn _var_os(key: &OsStr) -> Option<OsString> {
262-
os_imp::getenv(key)
262+
env_imp::getenv(key)
263263
}
264264

265265
/// The error type for operations interacting with environment variables.
@@ -363,7 +363,7 @@ impl Error for VarError {
363363
#[stable(feature = "env", since = "1.0.0")]
364364
pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
365365
let (key, value) = (key.as_ref(), value.as_ref());
366-
unsafe { os_imp::setenv(key, value) }.unwrap_or_else(|e| {
366+
unsafe { env_imp::setenv(key, value) }.unwrap_or_else(|e| {
367367
panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}")
368368
})
369369
}
@@ -434,7 +434,7 @@ pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
434434
#[stable(feature = "env", since = "1.0.0")]
435435
pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
436436
let key = key.as_ref();
437-
unsafe { os_imp::unsetenv(key) }
437+
unsafe { env_imp::unsetenv(key) }
438438
.unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}"))
439439
}
440440

std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ pub use core::primitive;
709709
// Re-export built-in macros defined through core.
710710
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
711711
#[allow(deprecated)]
712+
#[cfg_attr(bootstrap, allow(deprecated_in_future))]
712713
pub use core::{
713714
assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args,
714715
env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax,

std/src/prelude/v1.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub use crate::result::Result::{self, Err, Ok};
4646
// Re-exported built-in macros
4747
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
4848
#[allow(deprecated)]
49+
#[cfg_attr(bootstrap, allow(deprecated_in_future))]
4950
#[doc(no_inline)]
5051
pub use core::prelude::v1::{
5152
assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,

std/src/sys/args/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22
33
#![forbid(unsafe_op_in_unsafe_fn)]
44

5+
#[cfg(any(
6+
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),
7+
target_family = "windows",
8+
target_os = "hermit",
9+
target_os = "uefi",
10+
target_os = "wasi",
11+
target_os = "xous",
12+
))]
13+
mod common;
14+
515
cfg_if::cfg_if! {
616
if #[cfg(any(
717
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),

std/src/sys/args/uefi.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
use r_efi::protocols::loaded_image;
22

3+
pub use super::common::Args;
34
use crate::env::current_exe;
45
use crate::ffi::OsString;
56
use crate::iter::Iterator;
67
use crate::sys::pal::helpers;
78

8-
#[path = "common.rs"]
9-
mod common;
10-
pub use common::Args;
11-
129
pub fn args() -> Args {
1310
let lazy_current_exe = || Vec::from([current_exe().map(Into::into).unwrap_or_default()]);
1411

std/src/sys/args/unix.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@
55
66
#![allow(dead_code)] // runtime init functions not used during testing
77

8+
pub use super::common::Args;
89
use crate::ffi::CStr;
910
#[cfg(target_os = "hermit")]
1011
use crate::os::hermit::ffi::OsStringExt;
1112
#[cfg(not(target_os = "hermit"))]
1213
use crate::os::unix::ffi::OsStringExt;
1314

14-
#[path = "common.rs"]
15-
mod common;
16-
pub use common::Args;
17-
1815
/// One-time global initialization.
1916
pub unsafe fn init(argc: isize, argv: *const *const u8) {
2017
unsafe { imp::init(argc, argv) }

std/src/sys/args/wasi.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
#![forbid(unsafe_op_in_unsafe_fn)]
22

3+
pub use super::common::Args;
34
use crate::ffi::{CStr, OsStr, OsString};
45
use crate::os::wasi::ffi::OsStrExt;
56

6-
#[path = "common.rs"]
7-
mod common;
8-
pub use common::Args;
9-
107
/// Returns the command line arguments
118
pub fn args() -> Args {
129
Args::new(maybe_args().unwrap_or(Vec::new()))

std/src/sys/args/windows.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#[cfg(test)]
77
mod tests;
88

9+
pub use super::common::Args;
910
use crate::ffi::{OsStr, OsString};
1011
use crate::num::NonZero;
1112
use crate::os::windows::prelude::*;
@@ -18,10 +19,6 @@ use crate::sys_common::AsInner;
1819
use crate::sys_common::wstr::WStrUnits;
1920
use crate::{io, iter, ptr};
2021

21-
#[path = "common.rs"]
22-
mod common;
23-
pub use common::Args;
24-
2522
pub fn args() -> Args {
2623
// SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16
2724
// string so it's safe for `WStrUnits` to use.

std/src/sys/args/xous.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
pub use super::common::Args;
12
use crate::sys::pal::os::get_application_parameters;
23
use crate::sys::pal::os::params::ArgumentList;
34

4-
#[path = "common.rs"]
5-
mod common;
6-
pub use common::Args;
7-
85
pub fn args() -> Args {
96
let Some(params) = get_application_parameters() else {
107
return Args::new(vec![]);

std/src/sys/env/common.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::ffi::OsString;
2+
use crate::{fmt, vec};
3+
4+
pub struct Env {
5+
iter: vec::IntoIter<(OsString, OsString)>,
6+
}
7+
8+
// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
9+
pub struct EnvStrDebug<'a> {
10+
slice: &'a [(OsString, OsString)],
11+
}
12+
13+
impl fmt::Debug for EnvStrDebug<'_> {
14+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15+
f.debug_list()
16+
.entries(self.slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
17+
.finish()
18+
}
19+
}
20+
21+
impl Env {
22+
pub(super) fn new(env: Vec<(OsString, OsString)>) -> Self {
23+
Env { iter: env.into_iter() }
24+
}
25+
26+
pub fn str_debug(&self) -> impl fmt::Debug + '_ {
27+
EnvStrDebug { slice: self.iter.as_slice() }
28+
}
29+
}
30+
31+
impl fmt::Debug for Env {
32+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33+
f.debug_list().entries(self.iter.as_slice()).finish()
34+
}
35+
}
36+
37+
impl !Send for Env {}
38+
impl !Sync for Env {}
39+
40+
impl Iterator for Env {
41+
type Item = (OsString, OsString);
42+
fn next(&mut self) -> Option<(OsString, OsString)> {
43+
self.iter.next()
44+
}
45+
fn size_hint(&self) -> (usize, Option<usize>) {
46+
self.iter.size_hint()
47+
}
48+
}

std/src/sys/env/hermit.rs

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use core::slice::memchr;
2+
3+
pub use super::common::Env;
4+
use crate::collections::HashMap;
5+
use crate::ffi::{CStr, OsStr, OsString, c_char};
6+
use crate::io;
7+
use crate::os::hermit::ffi::OsStringExt;
8+
use crate::sync::Mutex;
9+
10+
static ENV: Mutex<Option<HashMap<OsString, OsString>>> = Mutex::new(None);
11+
12+
pub fn init(env: *const *const c_char) {
13+
let mut guard = ENV.lock().unwrap();
14+
let map = guard.insert(HashMap::new());
15+
16+
if env.is_null() {
17+
return;
18+
}
19+
20+
unsafe {
21+
let mut environ = env;
22+
while !(*environ).is_null() {
23+
if let Some((key, value)) = parse(CStr::from_ptr(*environ).to_bytes()) {
24+
map.insert(key, value);
25+
}
26+
environ = environ.add(1);
27+
}
28+
}
29+
30+
fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
31+
// Strategy (copied from glibc): Variable name and value are separated
32+
// by an ASCII equals sign '='. Since a variable name must not be
33+
// empty, allow variable names starting with an equals sign. Skip all
34+
// malformed lines.
35+
if input.is_empty() {
36+
return None;
37+
}
38+
let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
39+
pos.map(|p| {
40+
(
41+
OsStringExt::from_vec(input[..p].to_vec()),
42+
OsStringExt::from_vec(input[p + 1..].to_vec()),
43+
)
44+
})
45+
}
46+
}
47+
48+
/// Returns a vector of (variable, value) byte-vector pairs for all the
49+
/// environment variables of the current process.
50+
pub fn env() -> Env {
51+
let guard = ENV.lock().unwrap();
52+
let env = guard.as_ref().unwrap();
53+
54+
let result = env.iter().map(|(key, value)| (key.clone(), value.clone())).collect();
55+
56+
Env::new(result)
57+
}
58+
59+
pub fn getenv(k: &OsStr) -> Option<OsString> {
60+
ENV.lock().unwrap().as_ref().unwrap().get(k).cloned()
61+
}
62+
63+
pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
64+
let (k, v) = (k.to_owned(), v.to_owned());
65+
ENV.lock().unwrap().as_mut().unwrap().insert(k, v);
66+
Ok(())
67+
}
68+
69+
pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> {
70+
ENV.lock().unwrap().as_mut().unwrap().remove(k);
71+
Ok(())
72+
}

0 commit comments

Comments
 (0)