Skip to content

Commit 13e6873

Browse files
committed
Delegate to inner vec::IntoIter from env::ArgsOs
Delegate from `env::ArgsOs` to any methods which `vec::IntoIter` provides in traits. Since `env::ArgsOs` performs UTF-8 validation, it cannot benefit from this, as even skipped args should still be validated. Add `#[inline]` for any methods which simply wrap the inner iterator.
1 parent 2da29db commit 13e6873

File tree

5 files changed

+199
-21
lines changed

5 files changed

+199
-21
lines changed

library/std/src/env.rs

+64-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
use crate::error::Error;
1414
use crate::ffi::{OsStr, OsString};
15+
use crate::num::NonZero;
16+
use crate::ops::Try;
1517
use crate::path::{Path, PathBuf};
1618
use crate::sys::os as os_imp;
17-
use crate::{fmt, io, sys};
19+
use crate::{array, fmt, io, sys};
1820

1921
/// Returns the current working directory as a [`PathBuf`].
2022
///
@@ -872,19 +874,28 @@ impl !Sync for Args {}
872874
#[stable(feature = "env", since = "1.0.0")]
873875
impl Iterator for Args {
874876
type Item = String;
877+
875878
fn next(&mut self) -> Option<String> {
876879
self.inner.next().map(|s| s.into_string().unwrap())
877880
}
881+
882+
#[inline]
878883
fn size_hint(&self) -> (usize, Option<usize>) {
879884
self.inner.size_hint()
880885
}
886+
887+
// Methods which skip args cannot simply delegate to the inner iterator,
888+
// because that would bypass UTF-8 validation.
881889
}
882890

883891
#[stable(feature = "env", since = "1.0.0")]
884892
impl ExactSizeIterator for Args {
893+
#[inline]
885894
fn len(&self) -> usize {
886895
self.inner.len()
887896
}
897+
898+
#[inline]
888899
fn is_empty(&self) -> bool {
889900
self.inner.is_empty()
890901
}
@@ -914,29 +925,81 @@ impl !Sync for ArgsOs {}
914925
#[stable(feature = "env", since = "1.0.0")]
915926
impl Iterator for ArgsOs {
916927
type Item = OsString;
928+
929+
#[inline]
917930
fn next(&mut self) -> Option<OsString> {
918931
self.inner.next()
919932
}
933+
934+
#[inline]
935+
fn next_chunk<const N: usize>(
936+
&mut self,
937+
) -> Result<[OsString; N], array::IntoIter<OsString, N>> {
938+
self.inner.next_chunk()
939+
}
940+
941+
#[inline]
920942
fn size_hint(&self) -> (usize, Option<usize>) {
921943
self.inner.size_hint()
922944
}
945+
946+
#[inline]
947+
fn count(self) -> usize {
948+
self.inner.len()
949+
}
950+
951+
#[inline]
952+
fn last(self) -> Option<OsString> {
953+
self.inner.last()
954+
}
955+
956+
#[inline]
957+
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
958+
self.inner.advance_by(n)
959+
}
960+
961+
#[inline]
962+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
963+
where
964+
F: FnMut(B, Self::Item) -> R,
965+
R: Try<Output = B>,
966+
{
967+
self.inner.try_fold(init, f)
968+
}
969+
970+
#[inline]
971+
fn fold<B, F>(self, init: B, f: F) -> B
972+
where
973+
F: FnMut(B, Self::Item) -> B,
974+
{
975+
self.inner.fold(init, f)
976+
}
923977
}
924978

925979
#[stable(feature = "env", since = "1.0.0")]
926980
impl ExactSizeIterator for ArgsOs {
981+
#[inline]
927982
fn len(&self) -> usize {
928983
self.inner.len()
929984
}
985+
986+
#[inline]
930987
fn is_empty(&self) -> bool {
931988
self.inner.is_empty()
932989
}
933990
}
934991

935992
#[stable(feature = "env_iterators", since = "1.12.0")]
936993
impl DoubleEndedIterator for ArgsOs {
994+
#[inline]
937995
fn next_back(&mut self) -> Option<OsString> {
938996
self.inner.next_back()
939997
}
998+
999+
#[inline]
1000+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
1001+
self.inner.advance_back_by(n)
1002+
}
9401003
}
9411004

9421005
#[stable(feature = "std_debug", since = "1.16.0")]

library/std/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@
301301
#![feature(formatting_options)]
302302
#![feature(if_let_guard)]
303303
#![feature(intra_doc_pointers)]
304+
#![feature(iter_advance_by)]
305+
#![feature(iter_next_chunk)]
304306
#![feature(lang_items)]
305307
#![feature(let_chains)]
306308
#![feature(link_cfg)]
@@ -322,6 +324,7 @@
322324
#![feature(strict_provenance_lints)]
323325
#![feature(thread_local)]
324326
#![feature(try_blocks)]
327+
#![feature(try_trait_v2)]
325328
#![feature(type_alias_impl_trait)]
326329
// tidy-alphabetical-end
327330
//

library/std/src/sys/args/common.rs

+62-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::ffi::OsString;
2-
use crate::{fmt, vec};
2+
use crate::num::NonZero;
3+
use crate::ops::Try;
4+
use crate::{array, fmt, vec};
35

46
pub struct Args {
57
iter: vec::IntoIter<OsString>,
@@ -9,6 +11,7 @@ impl !Send for Args {}
911
impl !Sync for Args {}
1012

1113
impl Args {
14+
#[inline]
1215
pub(super) fn new(args: Vec<OsString>) -> Self {
1316
Args { iter: args.into_iter() }
1417
}
@@ -22,22 +25,77 @@ impl fmt::Debug for Args {
2225

2326
impl Iterator for Args {
2427
type Item = OsString;
28+
29+
#[inline]
2530
fn next(&mut self) -> Option<OsString> {
2631
self.iter.next()
2732
}
33+
34+
#[inline]
35+
fn next_chunk<const N: usize>(
36+
&mut self,
37+
) -> Result<[OsString; N], array::IntoIter<OsString, N>> {
38+
self.iter.next_chunk()
39+
}
40+
41+
#[inline]
2842
fn size_hint(&self) -> (usize, Option<usize>) {
2943
self.iter.size_hint()
3044
}
31-
}
3245

33-
impl ExactSizeIterator for Args {
34-
fn len(&self) -> usize {
46+
#[inline]
47+
fn count(self) -> usize {
3548
self.iter.len()
3649
}
50+
51+
#[inline]
52+
fn last(mut self) -> Option<OsString> {
53+
self.iter.next_back()
54+
}
55+
56+
#[inline]
57+
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
58+
self.iter.advance_by(n)
59+
}
60+
61+
#[inline]
62+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
63+
where
64+
F: FnMut(B, Self::Item) -> R,
65+
R: Try<Output = B>,
66+
{
67+
self.iter.try_fold(init, f)
68+
}
69+
70+
#[inline]
71+
fn fold<B, F>(self, init: B, f: F) -> B
72+
where
73+
F: FnMut(B, Self::Item) -> B,
74+
{
75+
self.iter.fold(init, f)
76+
}
3777
}
3878

3979
impl DoubleEndedIterator for Args {
80+
#[inline]
4081
fn next_back(&mut self) -> Option<OsString> {
4182
self.iter.next_back()
4283
}
84+
85+
#[inline]
86+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
87+
self.iter.advance_back_by(n)
88+
}
89+
}
90+
91+
impl ExactSizeIterator for Args {
92+
#[inline]
93+
fn len(&self) -> usize {
94+
self.iter.len()
95+
}
96+
97+
#[inline]
98+
fn is_empty(&self) -> bool {
99+
self.iter.is_empty()
100+
}
43101
}

library/std/src/sys/args/sgx.rs

+58-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![allow(fuzzy_provenance_casts)] // FIXME: this module systematically confuses pointers and integers
22

33
use crate::ffi::OsString;
4+
use crate::num::NonZero;
5+
use crate::ops::Try;
46
use crate::sync::atomic::{AtomicUsize, Ordering};
57
use crate::sys::os_str::Buf;
68
use crate::sys::pal::abi::usercalls::alloc;
@@ -27,35 +29,81 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
2729

2830
pub fn args() -> Args {
2931
let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
30-
if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
32+
let slice = args.map(|args| args.as_slice()).unwrap_or(&[]);
33+
Args { iter: slice.iter() }
3134
}
3235

33-
pub struct Args(slice::Iter<'static, OsString>);
36+
pub struct Args {
37+
iter: slice::Iter<'static, OsString>,
38+
}
3439

3540
impl fmt::Debug for Args {
3641
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37-
self.0.as_slice().fmt(f)
42+
self.iter.as_slice().fmt(f)
3843
}
3944
}
4045

4146
impl Iterator for Args {
4247
type Item = OsString;
48+
4349
fn next(&mut self) -> Option<OsString> {
44-
self.0.next().cloned()
50+
self.iter.next().cloned()
4551
}
52+
53+
#[inline]
4654
fn size_hint(&self) -> (usize, Option<usize>) {
47-
self.0.size_hint()
55+
self.iter.size_hint()
4856
}
49-
}
5057

51-
impl ExactSizeIterator for Args {
52-
fn len(&self) -> usize {
53-
self.0.len()
58+
#[inline]
59+
fn count(self) -> usize {
60+
self.iter.len()
61+
}
62+
63+
fn last(self) -> Option<OsString> {
64+
self.iter.last().cloned()
65+
}
66+
67+
#[inline]
68+
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
69+
self.iter.advance_by(n)
70+
}
71+
72+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
73+
where
74+
F: FnMut(B, Self::Item) -> R,
75+
R: Try<Output = B>,
76+
{
77+
self.iter.by_ref().cloned().try_fold(init, f)
78+
}
79+
80+
fn fold<B, F>(self, init: B, f: F) -> B
81+
where
82+
F: FnMut(B, Self::Item) -> B,
83+
{
84+
self.iter.cloned().fold(init, f)
5485
}
5586
}
5687

5788
impl DoubleEndedIterator for Args {
5889
fn next_back(&mut self) -> Option<OsString> {
59-
self.0.next_back().cloned()
90+
self.iter.next_back().cloned()
91+
}
92+
93+
#[inline]
94+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
95+
self.iter.advance_back_by(n)
96+
}
97+
}
98+
99+
impl ExactSizeIterator for Args {
100+
#[inline]
101+
fn len(&self) -> usize {
102+
self.iter.len()
103+
}
104+
105+
#[inline]
106+
fn is_empty(&self) -> bool {
107+
self.iter.is_empty()
60108
}
61109
}

library/std/src/sys/args/unsupported.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,28 @@ impl fmt::Debug for Args {
1515

1616
impl Iterator for Args {
1717
type Item = OsString;
18+
19+
#[inline]
1820
fn next(&mut self) -> Option<OsString> {
1921
None
2022
}
23+
24+
#[inline]
2125
fn size_hint(&self) -> (usize, Option<usize>) {
2226
(0, Some(0))
2327
}
2428
}
2529

26-
impl ExactSizeIterator for Args {
27-
fn len(&self) -> usize {
28-
0
29-
}
30-
}
31-
3230
impl DoubleEndedIterator for Args {
31+
#[inline]
3332
fn next_back(&mut self) -> Option<OsString> {
3433
None
3534
}
3635
}
36+
37+
impl ExactSizeIterator for Args {
38+
#[inline]
39+
fn len(&self) -> usize {
40+
0
41+
}
42+
}

0 commit comments

Comments
 (0)