Skip to content

Commit 9ee2cef

Browse files
committed
zkVM: Fix env::ArgsOs
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 rust-lang#139847.
1 parent 2da29db commit 9ee2cef

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
#![feature(formatting_options)]
302302
#![feature(if_let_guard)]
303303
#![feature(intra_doc_pointers)]
304+
#![feature(iter_advance_by)]
304305
#![feature(lang_items)]
305306
#![feature(let_chains)]
306307
#![feature(link_cfg)]

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

+54-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 {
@@ -38,44 +39,80 @@ impl Args {
3839
}
3940
}
4041

42+
impl !Send for Args {}
43+
impl !Sync for Args {}
44+
4145
impl fmt::Debug for Args {
4246
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43-
f.debug_list().finish()
47+
f.debug_list().entries(self.clone()).finish()
4448
}
4549
}
4650

4751
impl Iterator for Args {
4852
type Item = OsString;
4953

54+
#[inline]
5055
fn next(&mut self) -> Option<OsString> {
51-
if self.i_forward >= self.count - self.i_back {
56+
if self.front == self.back {
5257
None
5358
} else {
54-
let arg = Self::argv(self.i_forward);
55-
self.i_forward += 1;
59+
let arg = Self::argv(self.front);
60+
self.front += 1;
5661
Some(arg)
5762
}
5863
}
5964

65+
#[inline]
6066
fn size_hint(&self) -> (usize, Option<usize>) {
61-
(self.count, Some(self.count))
67+
let len = self.len();
68+
(len, Some(len))
6269
}
63-
}
6470

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

7189
impl DoubleEndedIterator for Args {
90+
#[inline]
7291
fn next_back(&mut self) -> Option<OsString> {
73-
if self.i_back >= self.count - self.i_forward {
92+
if self.back == self.front {
7493
None
7594
} else {
76-
let arg = Self::argv(self.count - 1 - self.i_back);
77-
self.i_back += 1;
78-
Some(arg)
95+
self.back -= 1;
96+
Some(Self::argv(self.back))
7997
}
8098
}
99+
100+
#[inline]
101+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
102+
let step_size = self.len().min(n);
103+
self.back -= step_size;
104+
NonZero::new(n - step_size).map_or(Ok(()), Err)
105+
}
106+
}
107+
108+
impl ExactSizeIterator for Args {
109+
#[inline]
110+
fn len(&self) -> usize {
111+
self.back - self.front
112+
}
113+
114+
#[inline]
115+
fn is_empty(&self) -> bool {
116+
self.front == self.back
117+
}
81118
}

0 commit comments

Comments
 (0)