Skip to content

Commit 93a672a

Browse files
committed
Fix env::ArgsOs for zkVM
The zkVM implementation of `env::ArgsOs` incorrectly reports the full length even after having iterated. Instead, use a range approach which works out to be simpler. Also, implement more iterator methods like the other platforms in #139847.
1 parent 2da29db commit 93a672a

File tree

1 file changed

+51
-17
lines changed

1 file changed

+51
-17
lines changed

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

+51-17
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
use crate::ffi::OsString;
22
use crate::fmt;
3+
use crate::num::NonZero;
34
use crate::sys::os_str;
45
use crate::sys::pal::{WORD_SIZE, abi};
56
use crate::sys_common::FromInner;
67

8+
#[derive(Clone)]
79
pub struct Args {
8-
i_forward: usize,
9-
i_back: usize,
10-
count: usize,
10+
front: usize,
11+
back: usize,
1112
}
1213

1314
pub fn args() -> Args {
1415
let count = unsafe { abi::sys_argc() };
15-
Args { i_forward: 0, i_back: 0, count }
16+
Args { front: 0, back: count }
1617
}
1718

1819
impl Args {
@@ -40,42 +41,75 @@ impl Args {
4041

4142
impl fmt::Debug for Args {
4243
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43-
f.debug_list().finish()
44+
f.debug_list().entries(self.clone()).finish()
4445
}
4546
}
4647

4748
impl Iterator for Args {
4849
type Item = OsString;
4950

51+
#[inline]
5052
fn next(&mut self) -> Option<OsString> {
51-
if self.i_forward >= self.count - self.i_back {
53+
if self.front == self.back {
5254
None
5355
} else {
54-
let arg = Self::argv(self.i_forward);
55-
self.i_forward += 1;
56+
let arg = Self::argv(self.front);
57+
self.front += 1;
5658
Some(arg)
5759
}
5860
}
5961

62+
#[inline]
6063
fn size_hint(&self) -> (usize, Option<usize>) {
61-
(self.count, Some(self.count))
64+
let len = self.len();
65+
(len, Some(len))
6266
}
63-
}
6467

65-
impl ExactSizeIterator for Args {
66-
fn len(&self) -> usize {
67-
self.count
68+
#[inline]
69+
fn count(self) -> usize {
70+
self.len()
71+
}
72+
73+
#[inline]
74+
fn last(mut self) -> Option<OsString> {
75+
self.next_back()
76+
}
77+
78+
#[inline]
79+
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
80+
let step_size = self.len().min(n);
81+
self.front += step_size;
82+
NonZero::new(n - step_size).map_or(Ok(()), Err)
6883
}
6984
}
7085

7186
impl DoubleEndedIterator for Args {
87+
#[inline]
7288
fn next_back(&mut self) -> Option<OsString> {
73-
if self.i_back >= self.count - self.i_forward {
89+
if self.back == self.front {
7490
None
7591
} else {
76-
let arg = Self::argv(self.count - 1 - self.i_back);
77-
self.i_back += 1;
78-
Some(arg)
92+
self.back -= 1;
93+
Some(Self::argv(self.back))
7994
}
8095
}
96+
97+
#[inline]
98+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
99+
let step_size = self.len().min(n);
100+
self.back -= step_size;
101+
NonZero::new(n - step_size).map_or(Ok(()), Err)
102+
}
103+
}
104+
105+
impl ExactSizeIterator for Args {
106+
#[inline]
107+
fn len(&self) -> usize {
108+
self.back - self.front
109+
}
110+
111+
#[inline]
112+
fn is_empty(&self) -> bool {
113+
self.front == self.back
114+
}
81115
}

0 commit comments

Comments
 (0)