about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/collections/hash/map.rs3
-rw-r--r--library/std/src/collections/hash/set.rs3
-rw-r--r--library/std/src/collections/mod.rs2
-rw-r--r--library/std/src/error.rs2
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/path.rs53
-rw-r--r--library/std/src/path/tests.rs9
-rw-r--r--library/std/src/sync/mutex.rs2
-rw-r--r--library/std/src/sync/rwlock.rs4
-rw-r--r--library/std/src/sys/unix/os.rs30
-rw-r--r--library/std/src/sys/unix/thread.rs16
-rw-r--r--library/std/src/time/monotonic.rs4
12 files changed, 91 insertions, 38 deletions
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 2de16ce3f86..528bb1bf6e9 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -625,14 +625,13 @@ where
     /// # Examples
     ///
     /// ```
-    /// #![feature(try_reserve)]
     /// use std::collections::HashMap;
     ///
     /// let mut map: HashMap<&str, isize> = HashMap::new();
     /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
     /// ```
     #[inline]
-    #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
+    #[stable(feature = "try_reserve", since = "1.57.0")]
     pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.base.try_reserve(additional).map_err(map_try_reserve_error)
     }
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 2613fbce156..dcfe3220950 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -423,13 +423,12 @@ where
     /// # Examples
     ///
     /// ```
-    /// #![feature(try_reserve)]
     /// use std::collections::HashSet;
     /// let mut set: HashSet<i32> = HashSet::new();
     /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
     /// ```
     #[inline]
-    #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
+    #[stable(feature = "try_reserve", since = "1.57.0")]
     pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.base.try_reserve(additional).map_err(map_try_reserve_error)
     }
diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs
index 6ca0525cdbe..a19c3431989 100644
--- a/library/std/src/collections/mod.rs
+++ b/library/std/src/collections/mod.rs
@@ -420,7 +420,7 @@ pub use self::hash_map::HashMap;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::hash_set::HashSet;
 
-#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
+#[stable(feature = "try_reserve", since = "1.57.0")]
 pub use alloc_crate::collections::TryReserveError;
 #[unstable(
     feature = "try_reserve_kind",
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index cc4ea27e57e..6ae0bc47a94 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -595,7 +595,7 @@ impl Error for char::ParseCharError {
     }
 }
 
-#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
+#[stable(feature = "try_reserve", since = "1.57.0")]
 impl Error for alloc::collections::TryReserveError {}
 
 #[unstable(feature = "duration_checked_float", issue = "83400")]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index b33a3c5d22f..0ba4e85886c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -331,7 +331,6 @@
 #![feature(total_cmp)]
 #![feature(trace_macros)]
 #![feature(try_blocks)]
-#![feature(try_reserve)]
 #![feature(try_reserve_kind)]
 #![feature(unboxed_closures)]
 #![feature(unwrap_infallible)]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 9d5778ed48c..a45ecf6ea8c 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1231,20 +1231,59 @@ impl PathBuf {
         let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
 
         // in the special case of `C:` on Windows, do *not* add a separator
+        let comps = self.components();
+
+        if comps.prefix_len() > 0
+            && comps.prefix_len() == comps.path.len()
+            && comps.prefix.unwrap().is_drive()
         {
-            let comps = self.components();
-            if comps.prefix_len() > 0
-                && comps.prefix_len() == comps.path.len()
-                && comps.prefix.unwrap().is_drive()
-            {
-                need_sep = false
-            }
+            need_sep = false
         }
 
         // absolute `path` replaces `self`
         if path.is_absolute() || path.prefix().is_some() {
             self.as_mut_vec().truncate(0);
 
+        // verbatim paths need . and .. removed
+        } else if comps.prefix_verbatim() {
+            let mut buf: Vec<_> = comps.collect();
+            for c in path.components() {
+                match c {
+                    Component::RootDir => {
+                        buf.truncate(1);
+                        buf.push(c);
+                    }
+                    Component::CurDir => (),
+                    Component::ParentDir => {
+                        if let Some(Component::Normal(_)) = buf.last() {
+                            buf.pop();
+                        }
+                    }
+                    _ => buf.push(c),
+                }
+            }
+
+            let mut res = OsString::new();
+            let mut need_sep = false;
+
+            for c in buf {
+                if need_sep && c != Component::RootDir {
+                    res.push(MAIN_SEP_STR);
+                }
+                res.push(c.as_os_str());
+
+                need_sep = match c {
+                    Component::RootDir => false,
+                    Component::Prefix(prefix) => {
+                        !prefix.parsed.is_drive() && prefix.parsed.len() > 0
+                    }
+                    _ => true,
+                }
+            }
+
+            self.inner = res;
+            return;
+
         // `path` has a root but no prefix, e.g., `\windows` (Windows only)
         } else if path.has_root() {
             let prefix_len = self.components().prefix_remaining();
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index ce23cf6cd21..3973a6829d3 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -1262,6 +1262,15 @@ pub fn test_push() {
         tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar");
 
         tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
+
+        tp!(r"\\?\C:\bar", "../foo", r"\\?\C:\foo");
+        tp!(r"\\?\C:\bar", "../../foo", r"\\?\C:\foo");
+        tp!(r"\\?\C:\", "../foo", r"\\?\C:\foo");
+        tp!(r"\\?\C:", r"D:\foo/./", r"D:\foo/./");
+        tp!(r"\\?\C:", r"\\?\D:\foo\.\", r"\\?\D:\foo\.\");
+        tp!(r"\\?\A:\x\y", "/foo", r"\\?\A:\foo");
+        tp!(r"\\?\A:", r"..\foo\.", r"\\?\A:\foo");
+        tp!(r"\\?\A:\x\y", r".\foo\.", r"\\?\A:\x\y\foo");
     }
 }
 
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index 0d844547376..57f1dcca30e 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -190,7 +190,7 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
 #[must_use = "if unused the Mutex will immediately unlock"]
 #[cfg_attr(
     not(bootstrap),
-    must_not_suspend = "Holding a MutexGuard across suspend \
+    must_not_suspend = "holding a MutexGuard across suspend \
                       points can cause deadlocks, delays, \
                       and cause Futures to not implement `Send`"
 )]
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index aa1ce82d967..2f4395ceefd 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -97,7 +97,7 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 #[must_use = "if unused the RwLock will immediately unlock"]
 #[cfg_attr(
     not(bootstrap),
-    must_not_suspend = "Holding a RwLockReadGuard across suspend \
+    must_not_suspend = "holding a RwLockReadGuard across suspend \
                       points can cause deadlocks, delays, \
                       and cause Futures to not implement `Send`"
 )]
@@ -123,7 +123,7 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
 #[must_use = "if unused the RwLock will immediately unlock"]
 #[cfg_attr(
     not(bootstrap),
-    must_not_suspend = "Holding a RwLockWriteGuard across suspend \
+    must_not_suspend = "holding a RwLockWriteGuard across suspend \
                       points can cause deadlocks, delays, \
                       and cause Future's to not implement `Send`"
 )]
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index 1d5ffb07321..87893d26912 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -380,20 +380,24 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(any(target_os = "solaris", target_os = "illumos"))]
 pub fn current_exe() -> io::Result<PathBuf> {
-    extern "C" {
-        fn getexecname() -> *const c_char;
-    }
-    unsafe {
-        let path = getexecname();
-        if path.is_null() {
-            Err(io::Error::last_os_error())
-        } else {
-            let filename = CStr::from_ptr(path).to_bytes();
-            let path = PathBuf::from(<OsStr as OsStrExt>::from_bytes(filename));
+    if let Ok(path) = crate::fs::read_link("/proc/self/path/a.out") {
+        Ok(path)
+    } else {
+        extern "C" {
+            fn getexecname() -> *const c_char;
+        }
+        unsafe {
+            let path = getexecname();
+            if path.is_null() {
+                Err(io::Error::last_os_error())
+            } else {
+                let filename = CStr::from_ptr(path).to_bytes();
+                let path = PathBuf::from(<OsStr as OsStrExt>::from_bytes(filename));
 
-            // Prepend a current working directory to the path if
-            // it doesn't contain an absolute pathname.
-            if filename[0] == b'/' { Ok(path) } else { getcwd().map(|cwd| cwd.join(path)) }
+                // Prepend a current working directory to the path if
+                // it doesn't contain an absolute pathname.
+                if filename[0] == b'/' { Ok(path) } else { getcwd().map(|cwd| cwd.join(path)) }
+            }
         }
     }
 }
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 05f51a46168..5631834eca6 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -339,14 +339,18 @@ pub fn available_concurrency() -> io::Result<NonZeroUsize> {
 
             Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
         } else if #[cfg(target_os = "haiku")] {
-            let mut sinfo: libc::system_info = crate::mem::zeroed();
-            let res = libc::get_system_info(&mut sinfo);
+            // system_info cpu_count field gets the static data set at boot time with `smp_set_num_cpus`
+            // `get_system_info` calls then `smp_get_num_cpus`
+            unsafe {
+                let mut sinfo: libc::system_info = crate::mem::zeroed();
+                let res = libc::get_system_info(&mut sinfo);
 
-            if res != libc::B_OK {
-                return Err(io::Error::last_os_error());
-            }
+                if res != libc::B_OK {
+                    return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
+                }
 
-            Ok(unsafe { NonZeroUsize::new_unchecked(sinfo.cpu_count as usize) })
+                Ok(NonZeroUsize::new_unchecked(sinfo.cpu_count as usize))
+            }
         } else {
             // FIXME: implement on vxWorks, Redox, l4re
             Err(io::Error::new_const(io::ErrorKind::Unsupported, &"Getting the number of hardware threads is not supported on the target platform"))
diff --git a/library/std/src/time/monotonic.rs b/library/std/src/time/monotonic.rs
index 198ae739b55..64f16245c2b 100644
--- a/library/std/src/time/monotonic.rs
+++ b/library/std/src/time/monotonic.rs
@@ -5,7 +5,7 @@ pub(super) fn monotonize(raw: time::Instant) -> time::Instant {
     inner::monotonize(raw)
 }
 
-#[cfg(all(target_has_atomic = "64", not(target_has_atomic = "128")))]
+#[cfg(any(all(target_has_atomic = "64", not(target_has_atomic = "128")), target_arch = "aarch64"))]
 pub mod inner {
     use crate::sync::atomic::AtomicU64;
     use crate::sync::atomic::Ordering::*;
@@ -71,7 +71,7 @@ pub mod inner {
     }
 }
 
-#[cfg(target_has_atomic = "128")]
+#[cfg(all(target_has_atomic = "128", not(target_arch = "aarch64")))]
 pub mod inner {
     use crate::sync::atomic::AtomicU128;
     use crate::sync::atomic::Ordering::*;