From fffe2723cd8eabffb96b9b458efa9fec07407d3a Mon Sep 17 00:00:00 2001
From: Christiaan Dirkx <christiaan@dirkx.email>
Date: Sat, 24 Apr 2021 09:11:54 +0200
Subject: [PATCH 1/2] Make `sys::args::Args` a type alias instead of wrapper

---
 library/std/src/env.rs                  |   6 +-
 library/std/src/sys/hermit/args.rs      | 105 ++++++------------------
 library/std/src/sys/sgx/args.rs         |  35 +-------
 library/std/src/sys/unix/args.rs        |  44 ++--------
 library/std/src/sys/unsupported/args.rs |  34 +-------
 library/std/src/sys/wasi/args.rs        |  40 +--------
 library/std/src/sys/windows/args.rs     |  37 +--------
 7 files changed, 46 insertions(+), 255 deletions(-)

diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 4403280efc11b..115a7e5dd6d44 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -817,7 +817,8 @@ impl DoubleEndedIterator for Args {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Args {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Args").field("inner", &self.inner.inner).finish()
+        let args = &AsRef::<[OsString]>::as_ref(&self.inner.inner);
+        f.debug_struct("Args").field("inner", args).finish()
     }
 }
 
@@ -858,7 +859,8 @@ impl DoubleEndedIterator for ArgsOs {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for ArgsOs {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("ArgsOs").field("inner", &self.inner).finish()
+        let args = &AsRef::<[OsString]>::as_ref(&self.inner);
+        f.debug_struct("ArgsOs").field("inner", args).finish()
     }
 }
 
diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs
index 1c7e1dd8d5778..524e3465cd333 100644
--- a/library/std/src/sys/hermit/args.rs
+++ b/library/std/src/sys/hermit/args.rs
@@ -1,94 +1,39 @@
-use crate::ffi::OsString;
-use crate::fmt;
-use crate::vec;
+use crate::ffi::{CStr, OsString};
+use crate::os::unix::ffi::OsStringExt;
+use crate::ptr;
+use crate::sys_common::mutex::StaticMutex;
+use crate::vec::IntoIter;
+
+static mut ARGC: isize = 0;
+static mut ARGV: *const *const u8 = ptr::null();
+static LOCK: StaticMutex = StaticMutex::new();
 
 /// One-time global initialization.
 pub unsafe fn init(argc: isize, argv: *const *const u8) {
-    imp::init(argc, argv)
+    let _guard = LOCK.lock();
+    ARGC = argc;
+    ARGV = argv;
 }
 
 /// One-time global cleanup.
 pub unsafe fn cleanup() {
-    imp::cleanup()
+    let _guard = LOCK.lock();
+    ARGC = 0;
+    ARGV = ptr::null();
 }
 
 /// Returns the command line arguments
 pub fn args() -> Args {
-    imp::args()
-}
-
-pub struct Args {
-    iter: vec::IntoIter<OsString>,
-}
-
-impl fmt::Debug for Args {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.iter.as_slice().fmt(f)
-    }
-}
-
-impl !Send for Args {}
-impl !Sync for Args {}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.iter.next()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.iter.len()
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.iter.next_back()
-    }
-}
-
-mod imp {
-    use super::Args;
-    use crate::ffi::{CStr, OsString};
-    use crate::os::unix::ffi::OsStringExt;
-    use crate::ptr;
-
-    use crate::sys_common::mutex::StaticMutex;
-
-    static mut ARGC: isize = 0;
-    static mut ARGV: *const *const u8 = ptr::null();
-    static LOCK: StaticMutex = StaticMutex::new();
-
-    pub unsafe fn init(argc: isize, argv: *const *const u8) {
+    unsafe {
         let _guard = LOCK.lock();
-        ARGC = argc;
-        ARGV = argv;
-    }
-
-    pub unsafe fn cleanup() {
-        let _guard = LOCK.lock();
-        ARGC = 0;
-        ARGV = ptr::null();
-    }
-
-    pub fn args() -> Args {
-        Args { iter: clone().into_iter() }
-    }
-
-    fn clone() -> Vec<OsString> {
-        unsafe {
-            let _guard = LOCK.lock();
-            (0..ARGC)
-                .map(|i| {
-                    let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
-                    OsStringExt::from_vec(cstr.to_bytes().to_vec())
-                })
-                .collect()
-        }
+        (0..ARGC)
+            .map(|i| {
+                let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8);
+                OsStringExt::from_vec(cstr.to_bytes().to_vec())
+            })
+            .collect::<Vec<_>>()
+            .into_iter()
     }
 }
+
+pub type Args = IntoIter<OsString>;
diff --git a/library/std/src/sys/sgx/args.rs b/library/std/src/sys/sgx/args.rs
index ef4176c4ac0f0..0e90088cf0e43 100644
--- a/library/std/src/sys/sgx/args.rs
+++ b/library/std/src/sys/sgx/args.rs
@@ -1,10 +1,9 @@
 use super::abi::usercalls::{alloc, raw::ByteBuffer};
 use crate::ffi::OsString;
-use crate::fmt;
-use crate::slice;
 use crate::sync::atomic::{AtomicUsize, Ordering};
 use crate::sys::os_str::Buf;
 use crate::sys_common::FromInner;
+use crate::vec::IntoIter;
 
 #[cfg_attr(test, linkage = "available_externally")]
 #[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
@@ -25,35 +24,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
 
 pub fn args() -> Args {
     let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
-    if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
+    if let Some(args) = args { args.clone().into_iter() } else { Vec::new().into_iter() }
 }
 
-pub struct Args(slice::Iter<'static, OsString>);
-
-impl fmt::Debug for Args {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.as_slice().fmt(f)
-    }
-}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.0.next().cloned()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.0.size_hint()
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.0.len()
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.0.next_back().cloned()
-    }
-}
+pub type Args = IntoIter<OsString>;
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index fc423e393d4a4..ed0cfa46781fc 100644
--- a/library/std/src/sys/unix/args.rs
+++ b/library/std/src/sys/unix/args.rs
@@ -6,8 +6,7 @@
 #![allow(dead_code)] // runtime init functions not used during testing
 
 use crate::ffi::OsString;
-use crate::fmt;
-use crate::vec;
+use crate::vec::IntoIter;
 
 /// One-time global initialization.
 pub unsafe fn init(argc: isize, argv: *const *const u8) {
@@ -24,40 +23,7 @@ pub fn args() -> Args {
     imp::args()
 }
 
-pub struct Args {
-    iter: vec::IntoIter<OsString>,
-}
-
-impl !Send for Args {}
-impl !Sync for Args {}
-
-impl fmt::Debug for Args {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.iter.as_slice().fmt(f)
-    }
-}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.iter.next()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.iter.len()
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.iter.next_back()
-    }
-}
+pub type Args = IntoIter<OsString>;
 
 #[cfg(any(
     target_os = "linux",
@@ -134,7 +100,7 @@ mod imp {
     }
 
     pub fn args() -> Args {
-        Args { iter: clone().into_iter() }
+        clone().into_iter()
     }
 
     fn clone() -> Vec<OsString> {
@@ -180,7 +146,7 @@ mod imp {
                 })
                 .collect::<Vec<_>>()
         };
-        Args { iter: vec.into_iter() }
+        vec.into_iter()
     }
 
     // As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs
@@ -247,6 +213,6 @@ mod imp {
             }
         }
 
-        Args { iter: res.into_iter() }
+        res.into_iter()
     }
 }
diff --git a/library/std/src/sys/unsupported/args.rs b/library/std/src/sys/unsupported/args.rs
index a2d75a6197633..a6504845fc97e 100644
--- a/library/std/src/sys/unsupported/args.rs
+++ b/library/std/src/sys/unsupported/args.rs
@@ -1,36 +1,8 @@
 use crate::ffi::OsString;
-use crate::fmt;
+use crate::vec::IntoIter;
 
-pub struct Args {}
+pub type Args = IntoIter<OsString>;
 
 pub fn args() -> Args {
-    Args {}
-}
-
-impl fmt::Debug for Args {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_list().finish()
-    }
-}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        None
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (0, Some(0))
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        0
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        None
-    }
+    Vec::new().into_iter()
 }
diff --git a/library/std/src/sys/wasi/args.rs b/library/std/src/sys/wasi/args.rs
index c42c310e3a254..e2cc858613575 100644
--- a/library/std/src/sys/wasi/args.rs
+++ b/library/std/src/sys/wasi/args.rs
@@ -1,20 +1,14 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::ffi::{CStr, OsStr, OsString};
-use crate::fmt;
 use crate::os::wasi::ffi::OsStrExt;
-use crate::vec;
+use crate::vec::IntoIter;
 
-pub struct Args {
-    iter: vec::IntoIter<OsString>,
-}
-
-impl !Send for Args {}
-impl !Sync for Args {}
+pub type Args = IntoIter<OsString>;
 
 /// Returns the command line arguments
 pub fn args() -> Args {
-    Args { iter: maybe_args().unwrap_or(Vec::new()).into_iter() }
+    maybe_args().unwrap_or(Vec::new()).into_iter()
 }
 
 fn maybe_args() -> Option<Vec<OsString>> {
@@ -32,31 +26,3 @@ fn maybe_args() -> Option<Vec<OsString>> {
         Some(ret)
     }
 }
-
-impl fmt::Debug for Args {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.iter.as_slice().fmt(f)
-    }
-}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.iter.next()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.iter.len()
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.iter.next_back()
-    }
-}
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index f1264130faf7a..9d54bf659c66e 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -4,13 +4,12 @@
 mod tests;
 
 use crate::ffi::OsString;
-use crate::fmt;
 use crate::os::windows::prelude::*;
 use crate::path::PathBuf;
 use crate::slice;
 use crate::sys::c;
 use crate::sys::windows::os::current_exe;
-use crate::vec;
+use crate::vec::IntoIter;
 
 use core::iter;
 
@@ -21,7 +20,7 @@ pub fn args() -> Args {
             current_exe().map(PathBuf::into_os_string).unwrap_or_else(|_| OsString::new())
         });
 
-        Args { parsed_args_list: parsed_args_list.into_iter() }
+        parsed_args_list.into_iter()
     }
 }
 
@@ -156,34 +155,4 @@ unsafe fn parse_lp_cmd_line<F: Fn() -> OsString>(
     ret_val
 }
 
-pub struct Args {
-    parsed_args_list: vec::IntoIter<OsString>,
-}
-
-impl fmt::Debug for Args {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.parsed_args_list.as_slice().fmt(f)
-    }
-}
-
-impl Iterator for Args {
-    type Item = OsString;
-    fn next(&mut self) -> Option<OsString> {
-        self.parsed_args_list.next()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.parsed_args_list.size_hint()
-    }
-}
-
-impl DoubleEndedIterator for Args {
-    fn next_back(&mut self) -> Option<OsString> {
-        self.parsed_args_list.next_back()
-    }
-}
-
-impl ExactSizeIterator for Args {
-    fn len(&self) -> usize {
-        self.parsed_args_list.len()
-    }
-}
+pub type Args = IntoIter<OsString>;

From f83194540d48e82535329179e0e8d2fc80e2c373 Mon Sep 17 00:00:00 2001
From: Christiaan Dirkx <christiaan@dirkx.email>
Date: Sat, 24 Apr 2021 09:25:03 +0200
Subject: [PATCH 2/2] Create `sys::args::Args` wrapper in `sys_common`

---
 library/std/src/env.rs             | 12 +++----
 library/std/src/sys_common/args.rs | 50 ++++++++++++++++++++++++++++++
 library/std/src/sys_common/mod.rs  |  1 +
 3 files changed, 56 insertions(+), 7 deletions(-)
 create mode 100644 library/std/src/sys_common/args.rs

diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 115a7e5dd6d44..cb6f88f1cd907 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -18,8 +18,8 @@ use crate::ffi::{OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::path::{Path, PathBuf};
-use crate::sys;
 use crate::sys::os as os_imp;
+use crate::sys_common;
 
 /// Returns the current working directory as a [`PathBuf`].
 ///
@@ -705,7 +705,7 @@ pub struct Args {
 /// [`env::args_os()`]: args_os
 #[stable(feature = "env", since = "1.0.0")]
 pub struct ArgsOs {
-    inner: sys::args::Args,
+    inner: sys_common::args::Args,
 }
 
 /// Returns the arguments that this program was started with (normally passed
@@ -777,7 +777,7 @@ pub fn args() -> Args {
 /// ```
 #[stable(feature = "env", since = "1.0.0")]
 pub fn args_os() -> ArgsOs {
-    ArgsOs { inner: sys::args::args() }
+    ArgsOs { inner: sys_common::args::Args::get() }
 }
 
 #[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
@@ -817,8 +817,7 @@ impl DoubleEndedIterator for Args {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Args {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let args = &AsRef::<[OsString]>::as_ref(&self.inner.inner);
-        f.debug_struct("Args").field("inner", args).finish()
+        f.debug_struct("Args").field("inner", &self.inner.inner).finish()
     }
 }
 
@@ -859,8 +858,7 @@ impl DoubleEndedIterator for ArgsOs {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for ArgsOs {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let args = &AsRef::<[OsString]>::as_ref(&self.inner);
-        f.debug_struct("ArgsOs").field("inner", args).finish()
+        f.debug_struct("ArgsOs").field("inner", &self.inner).finish()
     }
 }
 
diff --git a/library/std/src/sys_common/args.rs b/library/std/src/sys_common/args.rs
new file mode 100644
index 0000000000000..a4c19983981ef
--- /dev/null
+++ b/library/std/src/sys_common/args.rs
@@ -0,0 +1,50 @@
+use crate::convert::AsRef;
+use crate::ffi::OsString;
+use crate::fmt;
+use crate::sys::args as sys;
+
+pub struct Args(sys::Args);
+
+impl !Send for Args {}
+impl !Sync for Args {}
+
+impl Args {
+    pub fn get() -> Args {
+        Args(sys::args())
+    }
+}
+
+impl fmt::Debug for Args {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let args = &AsRef::<[OsString]>::as_ref(self);
+        args.fmt(f)
+    }
+}
+
+impl AsRef<[OsString]> for Args {
+    fn as_ref(&self) -> &[OsString] {
+        self.0.as_ref()
+    }
+}
+
+impl Iterator for Args {
+    type Item = OsString;
+    fn next(&mut self) -> Option<OsString> {
+        self.0.next()
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+impl ExactSizeIterator for Args {
+    fn len(&self) -> usize {
+        self.0.len()
+    }
+}
+
+impl DoubleEndedIterator for Args {
+    fn next_back(&mut self) -> Option<OsString> {
+        self.0.next_back()
+    }
+}
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 1a9caa22c9243..a37d9aae1b6a0 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -20,6 +20,7 @@
 #[cfg(test)]
 mod tests;
 
+pub mod args;
 pub mod backtrace;
 pub mod bytestring;
 pub mod condvar;