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/mod.rs62
-rw-r--r--library/std/src/f32/tests.rs13
-rw-r--r--library/std/src/f64/tests.rs13
-rw-r--r--library/std/src/io/buffered/bufreader.rs1
-rw-r--r--library/std/src/io/error.rs32
-rw-r--r--library/std/src/os/windows/fs.rs24
-rw-r--r--library/std/src/path.rs24
-rw-r--r--library/std/src/sys/pal/unix/fs.rs2
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs15
-rw-r--r--library/std/src/sys/pal/windows/args.rs2
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--library/std/src/sys/personality/dwarf/eh.rs6
-rw-r--r--library/std/src/sys/personality/gcc.rs13
13 files changed, 115 insertions, 94 deletions
diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs
index 3b04412e766..21bebff96b9 100644
--- a/library/std/src/collections/mod.rs
+++ b/library/std/src/collections/mod.rs
@@ -79,41 +79,49 @@
 //! see each type's documentation, and note that the names of actual methods may
 //! differ from the tables below on certain collections.
 //!
-//! Throughout the documentation, we will follow a few conventions. For all
-//! operations, the collection's size is denoted by n. If another collection is
-//! involved in the operation, it contains m elements. Operations which have an
-//! *amortized* cost are suffixed with a `*`. Operations with an *expected*
-//! cost are suffixed with a `~`.
+//! Throughout the documentation, we will adhere to the following conventions
+//! for operation notation:
 //!
-//! All amortized costs are for the potential need to resize when capacity is
-//! exhausted. If a resize occurs it will take *O*(*n*) time. Our collections never
-//! automatically shrink, so removal operations aren't amortized. Over a
-//! sufficiently large series of operations, the average cost per operation will
-//! deterministically equal the given cost.
+//! * The collection's size is denoted by `n`.
+//! * If a second collection is involved, its size is denoted by `m`.
+//! * Item indices are denoted by `i`.
+//! * Operations which have an *amortized* cost are suffixed with a `*`.
+//! * Operations with an *expected* cost are suffixed with a `~`.
 //!
-//! Only [`HashMap`] has expected costs, due to the probabilistic nature of hashing.
-//! It is theoretically possible, though very unlikely, for [`HashMap`] to
-//! experience worse performance.
+//! Calling operations that add to a collection will occasionally require a
+//! collection to be resized - an extra operation that takes *O*(*n*) time.
 //!
-//! ## Sequences
+//! *Amortized* costs are calculated to account for the time cost of such resize
+//! operations *over a sufficiently large series of operations*. An individual
+//! operation may be slower or faster due to the sporadic nature of collection
+//! resizing, however the average cost per operation will approach the amortized
+//! cost.
 //!
-//! |                | get(i)                 | insert(i)               | remove(i)              | append    | split_off(i)           |
-//! |----------------|------------------------|-------------------------|------------------------|-----------|------------------------|
-//! | [`Vec`]        | *O*(1)                 | *O*(*n*-*i*)*           | *O*(*n*-*i*)           | *O*(*m*)* | *O*(*n*-*i*)           |
-//! | [`VecDeque`]   | *O*(1)                 | *O*(min(*i*, *n*-*i*))* | *O*(min(*i*, *n*-*i*)) | *O*(*m*)* | *O*(min(*i*, *n*-*i*)) |
-//! | [`LinkedList`] | *O*(min(*i*, *n*-*i*)) | *O*(min(*i*, *n*-*i*))  | *O*(min(*i*, *n*-*i*)) | *O*(1)    | *O*(min(*i*, *n*-*i*)) |
+//! Rust's collections never automatically shrink, so removal operations aren't
+//! amortized.
 //!
-//! Note that where ties occur, [`Vec`] is generally going to be faster than [`VecDeque`], and
-//! [`VecDeque`] is generally going to be faster than [`LinkedList`].
+//! [`HashMap`] uses *expected* costs. It is theoretically possible, though very
+//! unlikely, for [`HashMap`] to experience significantly worse performance than
+//! the expected cost. This is due to the probabilistic nature of hashing - i.e.
+//! it is possible to generate a duplicate hash given some input key that will
+//! requires extra computation to correct.
 //!
-//! ## Maps
+//! ## Cost of Collection Operations
 //!
-//! For Sets, all operations have the cost of the equivalent Map operation.
 //!
-//! |              | get           | insert        | remove        | range         | append       |
-//! |--------------|---------------|---------------|---------------|---------------|--------------|
-//! | [`HashMap`]  | *O*(1)~       | *O*(1)~*      | *O*(1)~       | N/A           | N/A          |
-//! | [`BTreeMap`] | *O*(log(*n*)) | *O*(log(*n*)) | *O*(log(*n*)) | *O*(log(*n*)) | *O*(*n*+*m*) |
+//! |                | get(i)                 | insert(i)               | remove(i)              | append(Vec(m))    | split_off(i)           | range           | append       |
+//! |----------------|------------------------|-------------------------|------------------------|-------------------|------------------------|-----------------|--------------|
+//! | [`Vec`]        | *O*(1)                 | *O*(*n*-*i*)*           | *O*(*n*-*i*)           | *O*(*m*)*         | *O*(*n*-*i*)           | N/A             | N/A          |
+//! | [`VecDeque`]   | *O*(1)                 | *O*(min(*i*, *n*-*i*))* | *O*(min(*i*, *n*-*i*)) | *O*(*m*)*         | *O*(min(*i*, *n*-*i*)) | N/A             | N/A          |
+//! | [`LinkedList`] | *O*(min(*i*, *n*-*i*)) | *O*(min(*i*, *n*-*i*))  | *O*(min(*i*, *n*-*i*)) | *O*(1)            | *O*(min(*i*, *n*-*i*)) | N/A             | N/A          |
+//! | [`HashMap`]    | *O*(1)~                | *O*(1)~*                | *O*(1)~                | N/A               | N/A                    | N/A             | N/A          |
+//! | [`BTreeMap`]   | *O*(log(*n*))          | *O*(log(*n*))           | *O*(log(*n*))          | N/A               | N/A                    | *O*(log(*n*))   | *O*(*n*+*m*) |
+//!
+//! Note that where ties occur, [`Vec`] is generally going to be faster than
+//! [`VecDeque`], and [`VecDeque`] is generally going to be faster than
+//! [`LinkedList`].
+//!
+//! For Sets, all operations have the cost of the equivalent Map operation.
 //!
 //! # Correct and Efficient Usage of Collections
 //!
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
index 3a4c1c120a4..99cfcfb231d 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/src/f32/tests.rs
@@ -2,31 +2,24 @@ use crate::f32::consts;
 use crate::num::{FpCategory as Fp, *};
 
 /// Smallest number
-#[allow(dead_code)] // unused on x86
 const TINY_BITS: u32 = 0x1;
 
 /// Next smallest number
-#[allow(dead_code)] // unused on x86
 const TINY_UP_BITS: u32 = 0x2;
 
 /// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
-#[allow(dead_code)] // unused on x86
 const MAX_DOWN_BITS: u32 = 0x7f7f_fffe;
 
 /// Zeroed exponent, full significant
-#[allow(dead_code)] // unused on x86
 const LARGEST_SUBNORMAL_BITS: u32 = 0x007f_ffff;
 
 /// Exponent = 0b1, zeroed significand
-#[allow(dead_code)] // unused on x86
 const SMALLEST_NORMAL_BITS: u32 = 0x0080_0000;
 
 /// First pattern over the mantissa
-#[allow(dead_code)] // unused on x86
 const NAN_MASK1: u32 = 0x002a_aaaa;
 
 /// Second pattern over the mantissa
-#[allow(dead_code)] // unused on x86
 const NAN_MASK2: u32 = 0x0055_5555;
 
 #[allow(unused_macros)]
@@ -353,9 +346,6 @@ fn test_is_sign_negative() {
     assert!((-f32::NAN).is_sign_negative());
 }
 
-// Ignore test on x87 floating point, these platforms do not guarantee NaN
-// payloads are preserved and flush denormals to zero, failing the tests.
-#[cfg(not(target_arch = "x86"))]
 #[test]
 fn test_next_up() {
     let tiny = f32::from_bits(TINY_BITS);
@@ -386,9 +376,6 @@ fn test_next_up() {
     assert_f32_biteq!(nan2.next_up(), nan2);
 }
 
-// Ignore test on x87 floating point, these platforms do not guarantee NaN
-// payloads are preserved and flush denormals to zero, failing the tests.
-#[cfg(not(target_arch = "x86"))]
 #[test]
 fn test_next_down() {
     let tiny = f32::from_bits(TINY_BITS);
diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs
index bac8405f973..3fac2efe0d7 100644
--- a/library/std/src/f64/tests.rs
+++ b/library/std/src/f64/tests.rs
@@ -2,31 +2,24 @@ use crate::f64::consts;
 use crate::num::{FpCategory as Fp, *};
 
 /// Smallest number
-#[allow(dead_code)] // unused on x86
 const TINY_BITS: u64 = 0x1;
 
 /// Next smallest number
-#[allow(dead_code)] // unused on x86
 const TINY_UP_BITS: u64 = 0x2;
 
 /// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
-#[allow(dead_code)] // unused on x86
 const MAX_DOWN_BITS: u64 = 0x7fef_ffff_ffff_fffe;
 
 /// Zeroed exponent, full significant
-#[allow(dead_code)] // unused on x86
 const LARGEST_SUBNORMAL_BITS: u64 = 0x000f_ffff_ffff_ffff;
 
 /// Exponent = 0b1, zeroed significand
-#[allow(dead_code)] // unused on x86
 const SMALLEST_NORMAL_BITS: u64 = 0x0010_0000_0000_0000;
 
 /// First pattern over the mantissa
-#[allow(dead_code)] // unused on x86
 const NAN_MASK1: u64 = 0x000a_aaaa_aaaa_aaaa;
 
 /// Second pattern over the mantissa
-#[allow(dead_code)] // unused on x86
 const NAN_MASK2: u64 = 0x0005_5555_5555_5555;
 
 #[allow(unused_macros)]
@@ -343,9 +336,6 @@ fn test_is_sign_negative() {
     assert!((-f64::NAN).is_sign_negative());
 }
 
-// Ignore test on x87 floating point, these platforms do not guarantee NaN
-// payloads are preserved and flush denormals to zero, failing the tests.
-#[cfg(not(target_arch = "x86"))]
 #[test]
 fn test_next_up() {
     let tiny = f64::from_bits(TINY_BITS);
@@ -375,9 +365,6 @@ fn test_next_up() {
     assert_f64_biteq!(nan2.next_up(), nan2);
 }
 
-// Ignore test on x87 floating point, these platforms do not guarantee NaN
-// payloads are preserved and flush denormals to zero, failing the tests.
-#[cfg(not(target_arch = "x86"))]
 #[test]
 fn test_next_down() {
     let tiny = f64::from_bits(TINY_BITS);
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index cf226bd28d0..035afbb8368 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -267,6 +267,7 @@ impl<R: ?Sized> BufReader<R> {
 // This is only used by a test which asserts that the initialization-tracking is correct.
 #[cfg(test)]
 impl<R: ?Sized> BufReader<R> {
+    #[allow(missing_docs)]
     pub fn initialized(&self) -> usize {
         self.buf.initialized()
     }
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index e8ae1d99fbf..6ecd9469c17 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -223,10 +223,10 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionReset,
     /// The remote host is not reachable.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     HostUnreachable,
     /// The network containing the remote host is not reachable.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NetworkUnreachable,
     /// The connection was aborted (terminated) by the remote server.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -243,7 +243,7 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     AddrNotAvailable,
     /// The system's networking is down.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NetworkDown,
     /// The operation failed because a pipe was closed.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -259,18 +259,18 @@ pub enum ErrorKind {
     ///
     /// For example, a filesystem path was specified where one of the intermediate directory
     /// components was, in fact, a plain file.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NotADirectory,
     /// The filesystem object is, unexpectedly, a directory.
     ///
     /// A directory was specified when a non-directory was expected.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     IsADirectory,
     /// A non-empty directory was specified where an empty directory was expected.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     DirectoryNotEmpty,
     /// The filesystem or storage medium is read-only, but a write operation was attempted.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ReadOnlyFilesystem,
     /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
     ///
@@ -285,7 +285,7 @@ pub enum ErrorKind {
     ///
     /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
     /// by problems with the network or server.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     StaleNetworkFileHandle,
     /// A parameter was incorrect.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -319,13 +319,13 @@ pub enum ErrorKind {
     /// The underlying storage (typically, a filesystem) is full.
     ///
     /// This does not include out of quota errors.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     StorageFull,
     /// Seek on unseekable file.
     ///
     /// Seeking was attempted on an open file handle which is not suitable for seeking - for
     /// example, on Unix, a named pipe opened with `File::open`.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NotSeekable,
     /// Filesystem quota was exceeded.
     #[unstable(feature = "io_error_more", issue = "86442")]
@@ -335,22 +335,22 @@ pub enum ErrorKind {
     /// This might arise from a hard limit of the underlying filesystem or file access API, or from
     /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
     /// their own errors.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     FileTooLarge,
     /// Resource is busy.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ResourceBusy,
     /// Executable file is busy.
     ///
     /// An attempt was made to write to a file which is also in use as a running program.  (Not all
     /// operating systems detect this situation.)
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ExecutableFileBusy,
     /// Deadlock (avoided).
     ///
     /// A file locking operation would result in deadlock.  This situation is typically detected, if
     /// at all, on a best-effort basis.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     Deadlock,
     /// Cross-device or cross-filesystem (hard) link or rename.
     #[unstable(feature = "io_error_more", issue = "86442")]
@@ -358,7 +358,7 @@ pub enum ErrorKind {
     /// Too many (hard) links to the same filesystem object.
     ///
     /// The filesystem does not support making so many hardlinks to the same file.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     TooManyLinks,
     /// A filename was invalid.
     ///
@@ -369,7 +369,7 @@ pub enum ErrorKind {
     ///
     /// When trying to run an external program, a system or process limit on the size of the
     /// arguments would have been exceeded.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ArgumentListTooLong,
     /// This operation was interrupted.
     ///
diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs
index 3dcde43cfec..ddb8dbd8fee 100644
--- a/library/std/src/os/windows/fs.rs
+++ b/library/std/src/os/windows/fs.rs
@@ -298,7 +298,7 @@ impl OpenOptionsExt for OpenOptions {
 /// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
 ///
 /// [`BY_HANDLE_FILE_INFORMATION`]:
-///     https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
+///     https://docs.microsoft.com/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information
 #[stable(feature = "metadata_ext", since = "1.1.0")]
 pub trait MetadataExt {
     /// Returns the value of the `dwFileAttributes` field of this metadata.
@@ -322,7 +322,7 @@ pub trait MetadataExt {
     /// ```
     ///
     /// [File Attribute Constants]:
-    ///     https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+    ///     https://docs.microsoft.com/windows/win32/fileio/file-attribute-constants
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn file_attributes(&self) -> u32;
 
@@ -351,7 +351,7 @@ pub trait MetadataExt {
     /// }
     /// ```
     ///
-    /// [`FILETIME`]: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
+    /// [`FILETIME`]: https://docs.microsoft.com/windows/win32/api/minwinbase/ns-minwinbase-filetime
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn creation_time(&self) -> u64;
 
@@ -386,7 +386,7 @@ pub trait MetadataExt {
     /// }
     /// ```
     ///
-    /// [`FILETIME`]: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
+    /// [`FILETIME`]: https://docs.microsoft.com/windows/win32/api/minwinbase/ns-minwinbase-filetime
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn last_access_time(&self) -> u64;
 
@@ -419,11 +419,11 @@ pub trait MetadataExt {
     /// }
     /// ```
     ///
-    /// [`FILETIME`]: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
+    /// [`FILETIME`]: https://docs.microsoft.com/windows/win32/api/minwinbase/ns-minwinbase-filetime
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn last_write_time(&self) -> u64;
 
-    /// Returns the value of the `nFileSize{High,Low}` fields of this
+    /// Returns the value of the `nFileSize` fields of this
     /// metadata.
     ///
     /// The returned value does not have meaning for directories.
@@ -462,7 +462,7 @@ pub trait MetadataExt {
     #[unstable(feature = "windows_by_handle", issue = "63010")]
     fn number_of_links(&self) -> Option<u32>;
 
-    /// Returns the value of the `nFileIndex{Low,High}` fields of this
+    /// Returns the value of the `nFileIndex` fields of this
     /// metadata.
     ///
     /// This will return `None` if the `Metadata` instance was created from a
@@ -471,10 +471,14 @@ pub trait MetadataExt {
     #[unstable(feature = "windows_by_handle", issue = "63010")]
     fn file_index(&self) -> Option<u64>;
 
-    /// Returns the change time, which is the last time file metadata was changed, such as
-    /// renames, attributes, etc
+    /// Returns the value of the `ChangeTime` fields of this metadata.
     ///
-    /// This will return `None` if the `Metadata` instance was not created using the `FILE_BASIC_INFO` type.
+    /// `ChangeTime` is the last time file metadata was changed, such as
+    /// renames, attributes, etc.
+    ///
+    /// This will return `None` if `Metadata` instance was created from a call to
+    /// `DirEntry::metadata` or if the `target_vendor` is outside the current platform
+    /// support for this api.
     #[unstable(feature = "windows_change_time", issue = "121478")]
     fn change_time(&self) -> Option<u64>;
 }
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 506ad445b6b..c94df9b5366 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1153,6 +1153,21 @@ impl FusedIterator for Ancestors<'_> {}
 /// ```
 ///
 /// Which method works best depends on what kind of situation you're in.
+///
+/// Note that `PathBuf` does not always sanitize arguments, for example
+/// [`push`] allows paths built from strings which include separators:
+///
+/// use std::path::PathBuf;
+///
+/// let mut path = PathBuf::new();
+///
+/// path.push(r"C:\");
+/// path.push("windows");
+/// path.push(r"..\otherdir");
+/// path.push("system32");
+///
+/// The behaviour of `PathBuf` may be changed to a panic on such inputs
+/// in the future. [`Extend::extend`] should be used to add multi-part paths.
 #[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct PathBuf {
@@ -1391,6 +1406,9 @@ impl PathBuf {
     /// `file_name`. The new path will be a sibling of the original path.
     /// (That is, it will have the same parent.)
     ///
+    /// The argument is not sanitized, so can include separators. This
+    /// behaviour may be changed to a panic in the future.
+    ///
     /// [`self.file_name`]: Path::file_name
     /// [`pop`]: PathBuf::pop
     ///
@@ -1411,6 +1429,12 @@ impl PathBuf {
     ///
     /// buf.set_file_name("baz");
     /// assert!(buf == PathBuf::from("/baz"));
+    ///
+    /// buf.set_file_name("../b/c.txt");
+    /// assert!(buf == PathBuf::from("/../b/c.txt"));
+    ///
+    /// buf.set_file_name("baz");
+    /// assert!(buf == PathBuf::from("/../b/baz"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn set_file_name<S: AsRef<OsStr>>(&mut self, file_name: S) {
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 4ec577a0a01..d09cee2e89c 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1731,7 +1731,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
     run_path_with_cstr(original, &|original| {
         run_path_with_cstr(link, &|link| {
             cfg_if::cfg_if! {
-                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nto"))] {
+                if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70"))] {
                     // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
                     // it implementation-defined whether `link` follows symlinks, so rely on the
                     // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index 9ff44b54c41..728ce8d60f6 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -32,7 +32,8 @@ impl Drop for Handler {
     target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
-    target_os = "solaris"
+    target_os = "solaris",
+    target_os = "illumos",
 ))]
 mod imp {
     #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
@@ -280,7 +281,7 @@ mod imp {
         libc::SIGSTKSZ
     }
 
-    #[cfg(target_os = "solaris")]
+    #[cfg(any(target_os = "solaris", target_os = "illumos"))]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         let mut current_stack: libc::stack_t = crate::mem::zeroed();
         assert_eq!(libc::stack_getbounds(&mut current_stack), 0);
@@ -486,7 +487,12 @@ mod imp {
         Some(guardaddr..guardaddr + page_size)
     }
 
-    #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
+    #[cfg(any(
+        target_os = "macos",
+        target_os = "openbsd",
+        target_os = "solaris",
+        target_os = "illumos",
+    ))]
     // FIXME: I am probably not unsafe.
     unsafe fn current_guard() -> Option<Range<usize>> {
         let stackptr = get_stack_start()?;
@@ -569,7 +575,8 @@ mod imp {
     target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
-    target_os = "solaris"
+    target_os = "solaris",
+    target_os = "illumos",
 )))]
 mod imp {
     pub unsafe fn init() {}
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index 66e75a83571..77d82678f1d 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -20,7 +20,7 @@ use crate::{fmt, io, iter, vec};
 
 /// This is the const equivalent to `NonZero::new(n).unwrap()`
 ///
-/// FIXME: This can be removed once `Option::unwrap` is stably const.
+/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const.
 /// See the `const_option` feature (#67441).
 const fn non_zero_u16(n: u16) -> NonZero<u16> {
     match NonZero::new(n) {
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 1cc9a2b7ffa..f5ed3e4628e 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -122,6 +122,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
         c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
         c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
+        c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
         _ => {}
     }
 
@@ -139,6 +140,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         c::WSAEHOSTUNREACH => HostUnreachable,
         c::WSAENETDOWN => NetworkDown,
         c::WSAENETUNREACH => NetworkUnreachable,
+        c::WSAEDQUOT => FilesystemQuotaExceeded,
 
         _ => Uncategorized,
     }
diff --git a/library/std/src/sys/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs
index c37c3e442ae..778d8686f02 100644
--- a/library/std/src/sys/personality/dwarf/eh.rs
+++ b/library/std/src/sys/personality/dwarf/eh.rs
@@ -54,10 +54,10 @@ pub enum EHAction {
     Terminate,
 }
 
-/// 32-bit Apple ARM uses SjLj exceptions, except for watchOS.
+/// 32-bit ARM Darwin platforms uses SjLj exceptions.
 ///
-/// I.e. iOS and tvOS, as those are the only Apple OSes that used 32-bit ARM
-/// devices.
+/// The exception is watchOS armv7k (specifically that subarchitecture), which
+/// instead uses DWARF Call Frame Information (CFI) unwinding.
 ///
 /// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.4/clang/lib/Driver/ToolChains/Darwin.cpp#L3107-L3119>
 pub const USING_SJLJ_EXCEPTIONS: bool =
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index f6b1844e153..ad596ecff65 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -95,14 +95,15 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 
 cfg_if::cfg_if! {
     if #[cfg(all(
-            target_arch = "arm",
-            not(all(target_vendor = "apple", not(target_os = "watchos"))),
-            not(target_os = "netbsd"),
-        ))] {
+        target_arch = "arm",
+        not(target_vendor = "apple"),
+        not(target_os = "netbsd"),
+    ))] {
         /// personality fn called by [ARM EHABI][armeabi-eh]
         ///
-        /// Apple 32-bit ARM (but not watchOS) uses the default routine instead
-        /// since it uses "setjmp-longjmp" unwinding.
+        /// 32-bit ARM on iOS/tvOS/watchOS does not use ARM EHABI, it uses
+        /// either "setjmp-longjmp" unwinding or DWARF CFI unwinding, which is
+        /// handled by the default routine.
         ///
         /// [armeabi-eh]: https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         #[lang = "eh_personality"]