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.rs4
-rw-r--r--library/std/src/collections/hash/set.rs4
-rw-r--r--library/std/src/collections/mod.rs8
-rw-r--r--library/std/src/error.rs21
-rw-r--r--library/std/src/ffi/os_str.rs3
-rw-r--r--library/std/src/future.rs17
-rw-r--r--library/std/src/io/buffered/bufreader.rs1
-rw-r--r--library/std/src/io/buffered/bufwriter.rs14
-rw-r--r--library/std/src/io/copy.rs80
-rw-r--r--library/std/src/io/mod.rs7
-rw-r--r--library/std/src/io/util.rs17
-rw-r--r--library/std/src/io/util/tests.rs70
-rw-r--r--library/std/src/lib.rs12
-rw-r--r--library/std/src/macros.rs16
-rw-r--r--library/std/src/net/ip.rs14
-rw-r--r--library/std/src/panic.rs35
-rw-r--r--library/std/src/sys/windows/c.rs1
-rw-r--r--library/std/src/sys/windows/compat.rs153
-rw-r--r--library/std/src/sys/windows/thread_parker.rs12
19 files changed, 364 insertions, 125 deletions
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 829fc3817af..28a25572dd8 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -658,8 +658,7 @@ where
     /// down no lower than the supplied limit while maintaining the internal rules
     /// and possibly leaving some space in accordance with the resize policy.
     ///
-    /// Panics if the current capacity is smaller than the supplied
-    /// minimum capacity.
+    /// If the current capacity is less than the lower limit, this is a no-op.
     ///
     /// # Examples
     ///
@@ -679,7 +678,6 @@ where
     #[inline]
     #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
-        assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
         self.base.shrink_to(min_capacity);
     }
 
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index baa3026ff75..b08510d6b01 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -462,9 +462,7 @@ where
     /// down no lower than the supplied limit while maintaining the internal rules
     /// and possibly leaving some space in accordance with the resize policy.
     ///
-    /// Panics if the current capacity is smaller than the supplied
-    /// minimum capacity.
-    ///
+    /// If the current capacity is less than the lower limit, this is a no-op.
     /// # Examples
     ///
     /// ```
diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs
index a1aab767eb2..80a13d52a2a 100644
--- a/library/std/src/collections/mod.rs
+++ b/library/std/src/collections/mod.rs
@@ -110,10 +110,10 @@
 //!
 //! For Sets, all operations have the cost of the equivalent Map operation.
 //!
-//! |              | get       | insert    | remove    | predecessor | 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       | 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) |
 //!
 //! # Correct and Efficient Usage of Collections
 //!
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index ca83c409822..605d953f5da 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -486,6 +486,27 @@ impl<T: Error> Error for Box<T> {
     }
 }
 
+#[stable(feature = "error_by_ref", since = "1.51.0")]
+impl<'a, T: Error + ?Sized> Error for &'a T {
+    #[allow(deprecated, deprecated_in_future)]
+    fn description(&self) -> &str {
+        Error::description(&**self)
+    }
+
+    #[allow(deprecated)]
+    fn cause(&self) -> Option<&dyn Error> {
+        Error::cause(&**self)
+    }
+
+    fn source(&self) -> Option<&(dyn Error + 'static)> {
+        Error::source(&**self)
+    }
+
+    fn backtrace(&self) -> Option<&Backtrace> {
+        Error::backtrace(&**self)
+    }
+}
+
 #[stable(feature = "fmt_error", since = "1.11.0")]
 impl Error for fmt::Error {
     #[allow(deprecated)]
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 32f0f8a52f8..21060182d60 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -304,8 +304,7 @@ impl OsString {
     /// The capacity will remain at least as large as both the length
     /// and the supplied value.
     ///
-    /// Panics if the current capacity is smaller than the supplied
-    /// minimum capacity.
+    /// If the current capacity is less than the lower limit, this is a no-op.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/future.rs b/library/std/src/future.rs
deleted file mode 100644
index 9d9c36e9afb..00000000000
--- a/library/std/src/future.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//! Asynchronous values.
-
-#[doc(inline)]
-#[stable(feature = "futures_api", since = "1.36.0")]
-pub use core::future::Future;
-
-#[doc(inline)]
-#[unstable(feature = "gen_future", issue = "50547")]
-pub use core::future::{from_generator, get_context, ResumeTy};
-
-#[doc(inline)]
-#[stable(feature = "future_readiness_fns", since = "1.48.0")]
-pub use core::future::{pending, ready, Pending, Ready};
-
-#[doc(inline)]
-#[unstable(feature = "into_future", issue = "67644")]
-pub use core::future::IntoFuture;
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 8bae3da1273..987371f50ec 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -410,7 +410,6 @@ impl<R: Seek> Seek for BufReader<R> {
     /// # Example
     ///
     /// ```no_run
-    /// #![feature(seek_convenience)]
     /// use std::{
     ///     io::{self, BufRead, BufReader, Seek},
     ///     fs::File,
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index fa7bd0d72d1..65bc2fcf00a 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -117,7 +117,7 @@ impl<W: Write> BufWriter<W> {
     /// "successfully written" (by returning nonzero success values from
     /// `write`), any 0-length writes from `inner` must be reported as i/o
     /// errors from this method.
-    pub(super) fn flush_buf(&mut self) -> io::Result<()> {
+    pub(in crate::io) fn flush_buf(&mut self) -> io::Result<()> {
         /// Helper struct to ensure the buffer is updated after all the writes
         /// are complete. It tracks the number of written bytes and drains them
         /// all from the front of the buffer when dropped.
@@ -243,6 +243,18 @@ impl<W: Write> BufWriter<W> {
         &self.buf
     }
 
+    /// Returns a mutable reference to the internal buffer.
+    ///
+    /// This can be used to write data directly into the buffer without triggering writers
+    /// to the underlying writer.
+    ///
+    /// That the buffer is a `Vec` is an implementation detail.
+    /// Callers should not modify the capacity as there currently is no public API to do so
+    /// and thus any capacity changes would be unexpected by the user.
+    pub(in crate::io) fn buffer_mut(&mut self) -> &mut Vec<u8> {
+        &mut self.buf
+    }
+
     /// Returns the number of bytes the internal buffer can hold without flushing.
     ///
     /// # Examples
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index b88bca2f2b4..3780f2044cb 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -1,4 +1,4 @@
-use crate::io::{self, ErrorKind, Read, Write};
+use super::{BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
 use crate::mem::MaybeUninit;
 
 /// Copies the entire contents of a reader into a writer.
@@ -40,7 +40,7 @@ use crate::mem::MaybeUninit;
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
+pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
 where
     R: Read,
     W: Write,
@@ -54,14 +54,82 @@ where
     }
 }
 
-/// The general read-write-loop implementation of
-/// `io::copy` that is used when specializations are not available or not applicable.
-pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
+/// The userspace read-write-loop implementation of `io::copy` that is used when
+/// OS-specific specializations for copy offloading are not available or not applicable.
+pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
 where
     R: Read,
     W: Write,
 {
-    let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit();
+    BufferedCopySpec::copy_to(reader, writer)
+}
+
+/// Specialization of the read-write loop that either uses a stack buffer
+/// or reuses the internal buffer of a BufWriter
+trait BufferedCopySpec: Write {
+    fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64>;
+}
+
+impl<W: Write + ?Sized> BufferedCopySpec for W {
+    default fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
+        stack_buffer_copy(reader, writer)
+    }
+}
+
+impl<I: Write> BufferedCopySpec for BufWriter<I> {
+    fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
+        if writer.capacity() < DEFAULT_BUF_SIZE {
+            return stack_buffer_copy(reader, writer);
+        }
+
+        // FIXME: #42788
+        //
+        //   - This creates a (mut) reference to a slice of
+        //     _uninitialized_ integers, which is **undefined behavior**
+        //
+        //   - Only the standard library gets to soundly "ignore" this,
+        //     based on its privileged knowledge of unstable rustc
+        //     internals;
+        unsafe {
+            let spare_cap = writer.buffer_mut().spare_capacity_mut();
+            reader.initializer().initialize(MaybeUninit::slice_assume_init_mut(spare_cap));
+        }
+
+        let mut len = 0;
+
+        loop {
+            let buf = writer.buffer_mut();
+            let spare_cap = buf.spare_capacity_mut();
+
+            if spare_cap.len() >= DEFAULT_BUF_SIZE {
+                match reader.read(unsafe { MaybeUninit::slice_assume_init_mut(spare_cap) }) {
+                    Ok(0) => return Ok(len), // EOF reached
+                    Ok(bytes_read) => {
+                        assert!(bytes_read <= spare_cap.len());
+                        // Safety: The initializer contract guarantees that either it or `read`
+                        // will have initialized these bytes. And we just checked that the number
+                        // of bytes is within the buffer capacity.
+                        unsafe { buf.set_len(buf.len() + bytes_read) };
+                        len += bytes_read as u64;
+                        // Read again if the buffer still has enough capacity, as BufWriter itself would do
+                        // This will occur if the reader returns short reads
+                        continue;
+                    }
+                    Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+                    Err(e) => return Err(e),
+                }
+            }
+
+            writer.flush_buf()?;
+        }
+    }
+}
+
+fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
+    reader: &mut R,
+    writer: &mut W,
+) -> Result<u64> {
+    let mut buf = MaybeUninit::<[u8; DEFAULT_BUF_SIZE]>::uninit();
     // FIXME: #42788
     //
     //   - This creates a (mut) reference to a slice of
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index c87a56586c6..db3b0e2628f 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1671,7 +1671,7 @@ pub trait Seek {
     /// # Example
     ///
     /// ```no_run
-    /// #![feature(seek_convenience)]
+    /// #![feature(seek_stream_len)]
     /// use std::{
     ///     io::{self, Seek},
     ///     fs::File,
@@ -1685,7 +1685,7 @@ pub trait Seek {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "seek_convenience", issue = "59359")]
+    #[unstable(feature = "seek_stream_len", issue = "59359")]
     fn stream_len(&mut self) -> Result<u64> {
         let old_pos = self.stream_position()?;
         let len = self.seek(SeekFrom::End(0))?;
@@ -1706,7 +1706,6 @@ pub trait Seek {
     /// # Example
     ///
     /// ```no_run
-    /// #![feature(seek_convenience)]
     /// use std::{
     ///     io::{self, BufRead, BufReader, Seek},
     ///     fs::File,
@@ -1723,7 +1722,7 @@ pub trait Seek {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "seek_convenience", issue = "59359")]
+    #[stable(feature = "seek_convenience", since = "1.51.0")]
     fn stream_position(&mut self) -> Result<u64> {
         self.seek(SeekFrom::Current(0))
     }
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index db845457c96..e43ce4cdb4b 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -4,7 +4,7 @@
 mod tests;
 
 use crate::fmt;
-use crate::io::{self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Write};
+use crate::io::{self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
 
 /// A reader which is always at EOF.
 ///
@@ -58,6 +58,21 @@ impl BufRead for Empty {
     fn consume(&mut self, _n: usize) {}
 }
 
+#[stable(feature = "empty_seek", since = "1.51.0")]
+impl Seek for Empty {
+    fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> {
+        Ok(0)
+    }
+
+    fn stream_len(&mut self) -> io::Result<u64> {
+        Ok(0)
+    }
+
+    fn stream_position(&mut self) -> io::Result<u64> {
+        Ok(0)
+    }
+}
+
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Empty {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs
index 9450b1ee124..7632eaf872a 100644
--- a/library/std/src/io/util/tests.rs
+++ b/library/std/src/io/util/tests.rs
@@ -1,5 +1,8 @@
+use crate::cmp::{max, min};
 use crate::io::prelude::*;
-use crate::io::{copy, empty, repeat, sink, Empty, Repeat, Sink};
+use crate::io::{
+    copy, empty, repeat, sink, BufWriter, Empty, Repeat, Result, SeekFrom, Sink, DEFAULT_BUF_SIZE,
+};
 
 #[test]
 fn copy_copies() {
@@ -11,6 +14,51 @@ fn copy_copies() {
     assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17);
 }
 
+struct ShortReader {
+    cap: usize,
+    read_size: usize,
+    observed_buffer: usize,
+}
+
+impl Read for ShortReader {
+    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
+        let bytes = min(self.cap, self.read_size);
+        self.cap -= bytes;
+        self.observed_buffer = max(self.observed_buffer, buf.len());
+        Ok(bytes)
+    }
+}
+
+struct WriteObserver {
+    observed_buffer: usize,
+}
+
+impl Write for WriteObserver {
+    fn write(&mut self, buf: &[u8]) -> Result<usize> {
+        self.observed_buffer = max(self.observed_buffer, buf.len());
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> Result<()> {
+        Ok(())
+    }
+}
+
+#[test]
+fn copy_specializes_bufwriter() {
+    let cap = 117 * 1024;
+    let buf_sz = 16 * 1024;
+    let mut r = ShortReader { cap, observed_buffer: 0, read_size: 1337 };
+    let mut w = BufWriter::with_capacity(buf_sz, WriteObserver { observed_buffer: 0 });
+    assert_eq!(
+        copy(&mut r, &mut w).unwrap(),
+        cap as u64,
+        "expected the whole capacity to be copied"
+    );
+    assert_eq!(r.observed_buffer, buf_sz, "expected a large buffer to be provided to the reader");
+    assert!(w.get_mut().observed_buffer > DEFAULT_BUF_SIZE, "expected coalesced writes");
+}
+
 #[test]
 fn sink_sinks() {
     let mut s = sink();
@@ -30,6 +78,26 @@ fn empty_reads() {
 }
 
 #[test]
+fn empty_seeks() {
+    let mut e = empty();
+    assert!(matches!(e.seek(SeekFrom::Start(0)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::Start(1)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::Start(u64::MAX)), Ok(0)));
+
+    assert!(matches!(e.seek(SeekFrom::End(i64::MIN)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::End(-1)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::End(0)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::End(1)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::End(i64::MAX)), Ok(0)));
+
+    assert!(matches!(e.seek(SeekFrom::Current(i64::MIN)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::Current(-1)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::Current(0)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::Current(1)), Ok(0)));
+    assert!(matches!(e.seek(SeekFrom::Current(i64::MAX)), Ok(0)));
+}
+
+#[test]
 fn repeat_repeats() {
     let mut r = repeat(4);
     let mut b = [0; 1024];
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 5ba13c2f913..b6929f59395 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -224,6 +224,7 @@
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
+#![feature(async_stream)]
 #![feature(arbitrary_self_types)]
 #![feature(array_error_internals)]
 #![feature(asm)]
@@ -258,6 +259,7 @@
 #![feature(dropck_eyepatch)]
 #![feature(duration_constants)]
 #![feature(duration_zero)]
+#![feature(edition_panic)]
 #![feature(exact_size_is_empty)]
 #![feature(exhaustive_patterns)]
 #![feature(extend_one)]
@@ -282,6 +284,7 @@
 #![feature(maybe_uninit_extra)]
 #![feature(maybe_uninit_ref)]
 #![feature(maybe_uninit_slice)]
+#![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
 #![feature(needs_panic_runtime)]
 #![feature(negative_impls)]
@@ -298,7 +301,6 @@
 #![feature(prelude_import)]
 #![feature(ptr_internals)]
 #![feature(raw)]
-#![feature(raw_ref_macros)]
 #![feature(ready_macro)]
 #![feature(rustc_attrs)]
 #![feature(rustc_private)]
@@ -326,6 +328,7 @@
 #![feature(unsafe_cell_raw_get)]
 #![feature(unwind_attributes)]
 #![feature(vec_into_raw_parts)]
+#![feature(vec_spare_capacity)]
 #![feature(wake_trait)]
 // NB: the above list is sorted to minimize merge conflicts.
 #![default_lib_allocator]
@@ -406,6 +409,8 @@ pub use core::cmp;
 pub use core::convert;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::default;
+#[stable(feature = "futures_api", since = "1.36.0")]
+pub use core::future;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::hash;
 #[stable(feature = "core_hint", since = "1.27.0")]
@@ -448,6 +453,8 @@ pub use core::ptr;
 pub use core::raw;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::result;
+#[unstable(feature = "async_stream", issue = "79024")]
+pub use core::stream;
 #[stable(feature = "i128", since = "1.26.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::u128;
@@ -505,9 +512,6 @@ pub mod task {
     pub use alloc::task::*;
 }
 
-#[stable(feature = "futures_api", since = "1.36.0")]
-pub mod future;
-
 // Platform-abstraction modules
 #[macro_use]
 mod sys_common;
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index e466f315152..0ce6542cb72 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -4,6 +4,7 @@
 //! library. Each macro is available for use when linking against the standard
 //! library.
 
+#[cfg(bootstrap)]
 #[doc(include = "../../core/src/macros/panic.md")]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -17,6 +18,21 @@ macro_rules! panic {
     });
 }
 
+#[cfg(not(bootstrap))]
+#[doc(include = "../../core/src/macros/panic.md")]
+#[macro_export]
+#[rustc_builtin_macro = "std_panic"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable(edition_panic)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
+macro_rules! panic {
+    // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
+    // depending on the edition of the caller.
+    ($($arg:tt)*) => {
+        /* compiler built-in */
+    };
+}
+
 /// Prints to the standard output.
 ///
 /// Equivalent to the [`println!`] macro except that a newline is not printed at
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 84449e48767..a8a4127d40a 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -1217,8 +1217,8 @@ impl Ipv6Addr {
 
     /// Returns [`true`] if the address is a unicast link-local address (`fe80::/64`).
     ///
-    /// A common mis-conception is to think that "unicast link-local addresses start with
-    /// `fe80::`", but the [IETF RFC 4291] actually defines a stricter format for these addresses:
+    /// A common misconception is to think that "unicast link-local addresses start with
+    /// `fe80::`", but [IETF RFC 4291] actually defines a stricter format for these addresses:
     ///
     /// ```no_rust
     /// |   10     |
@@ -1228,9 +1228,9 @@ impl Ipv6Addr {
     /// +----------+-------------------------+----------------------------+
     /// ```
     ///
-    /// This method validates the format defined in the RFC and won't recognize the following
-    /// addresses such as `fe80:0:0:1::` or `fe81::` as unicast link-local addresses for example.
-    /// If you need a less strict validation use [`Ipv6Addr::is_unicast_link_local()`] instead.
+    /// This method validates the format defined in the RFC and won't recognize addresses
+    /// like `fe80:0:0:1::` or `fe81::` as unicast link-local addresses.
+    /// If you need a less strict validation, use [`Ipv6Addr::is_unicast_link_local()`] instead.
     ///
     /// # Examples
     ///
@@ -1282,7 +1282,7 @@ impl Ipv6Addr {
     /// +----------+-------------------------+----------------------------+
     /// ```
     ///
-    /// As a result, this method consider addresses such as `fe80:0:0:1::` or `fe81::` to be
+    /// As a result, this method considers addresses such as `fe80:0:0:1::` or `fe81::` to be
     /// unicast link-local addresses, whereas [`Ipv6Addr::is_unicast_link_local_strict()`] does not.
     /// If you need a strict validation fully compliant with the RFC, use
     /// [`Ipv6Addr::is_unicast_link_local_strict()`] instead.
@@ -1362,7 +1362,7 @@ impl Ipv6Addr {
     }
 
     /// Returns [`true`] if this is an address reserved for documentation
-    /// (2001:db8::/32).
+    /// (`2001:db8::/32`).
     ///
     /// This property is defined in [IETF RFC 3849].
     ///
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 0f568da459b..89a822a7229 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -12,11 +12,33 @@ use crate::panicking;
 use crate::pin::Pin;
 use crate::ptr::{NonNull, Unique};
 use crate::rc::Rc;
+use crate::stream::Stream;
 use crate::sync::atomic;
 use crate::sync::{Arc, Mutex, RwLock};
 use crate::task::{Context, Poll};
 use crate::thread::Result;
 
+#[doc(hidden)]
+#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
+#[allow_internal_unstable(libstd_sys_internals)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
+#[rustc_macro_transparency = "semitransparent"]
+pub macro panic_2015 {
+    () => ({
+        $crate::rt::begin_panic("explicit panic")
+    }),
+    ($msg:expr $(,)?) => ({
+        $crate::rt::begin_panic($msg)
+    }),
+    ($fmt:expr, $($arg:tt)+) => ({
+        $crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+))
+    }),
+}
+
+#[doc(hidden)]
+#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
+pub use core::panic::panic_2021;
+
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 pub use crate::panicking::{set_hook, take_hook};
 
@@ -340,6 +362,19 @@ impl<F: Future> Future for AssertUnwindSafe<F> {
     }
 }
 
+#[unstable(feature = "async_stream", issue = "79024")]
+impl<S: Stream> Stream for AssertUnwindSafe<S> {
+    type Item = S::Item;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
+        unsafe { self.map_unchecked_mut(|x| &mut x.0) }.poll_next(cx)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
 /// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
 ///
 /// This function will return `Ok` with the closure's result if the closure
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index f43a19d91b6..dec88620810 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -975,6 +975,7 @@ extern "system" {
     pub fn freeaddrinfo(res: *mut ADDRINFOA);
 
     pub fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void;
+    pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE;
     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
 
     pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs
index e9588e29758..017a4bbe97c 100644
--- a/library/std/src/sys/windows/compat.rs
+++ b/library/std/src/sys/windows/compat.rs
@@ -1,93 +1,116 @@
-//! A "compatibility layer" for spanning XP and Windows 7
+//! A "compatibility layer" for supporting older versions of Windows
 //!
-//! The standard library currently binds many functions that are not available
-//! on Windows XP, but we would also like to support building executables that
-//! run on XP. To do this we specify all non-XP APIs as having a fallback
-//! implementation to do something reasonable.
+//! The standard library uses some Windows API functions that are not present
+//! on older versions of Windows.  (Note that the oldest version of Windows
+//! that Rust supports is Windows 7 (client) and Windows Server 2008 (server).)
+//! This module implements a form of delayed DLL import binding, using
+//! `GetModuleHandle` and `GetProcAddress` to look up DLL entry points at
+//! runtime.
 //!
-//! This dynamic runtime detection of whether a function is available is
-//! implemented with `GetModuleHandle` and `GetProcAddress` paired with a
-//! static-per-function which caches the result of the first check. In this
-//! manner we pay a semi-large one-time cost up front for detecting whether a
-//! function is available but afterwards it's just a load and a jump.
-
-use crate::ffi::CString;
-use crate::sys::c;
-
-pub fn lookup(module: &str, symbol: &str) -> Option<usize> {
-    let mut module: Vec<u16> = module.encode_utf16().collect();
-    module.push(0);
-    let symbol = CString::new(symbol).unwrap();
-    unsafe {
-        let handle = c::GetModuleHandleW(module.as_ptr());
-        match c::GetProcAddress(handle, symbol.as_ptr()) as usize {
-            0 => None,
-            n => Some(n),
-        }
-    }
-}
+//! This implementation uses a static initializer to look up the DLL entry
+//! points. The CRT (C runtime) executes static initializers before `main`
+//! is called (for binaries) and before `DllMain` is called (for DLLs).
+//! This is the ideal time to look up DLL imports, because we are guaranteed
+//! that no other threads will attempt to call these entry points. Thus,
+//! we can look up the imports and store them in `static mut` fields
+//! without any synchronization.
+//!
+//! This has an additional advantage: Because the DLL import lookup happens
+//! at module initialization, the cost of these lookups is deterministic,
+//! and is removed from the code paths that actually call the DLL imports.
+//! That is, there is no unpredictable "cache miss" that occurs when calling
+//! a DLL import. For applications that benefit from predictable delays,
+//! this is a benefit. This also eliminates the comparison-and-branch
+//! from the hot path.
+//!
+//! Currently, the standard library uses only a small number of dynamic
+//! DLL imports. If this number grows substantially, then the cost of
+//! performing all of the lookups at initialization time might become
+//! substantial.
+//!
+//! The mechanism of registering a static initializer with the CRT is
+//! documented in
+//! [CRT Initialization](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-160).
+//! It works by contributing a global symbol to the `.CRT$XCU` section.
+//! The linker builds a table of all static initializer functions.
+//! The CRT startup code then iterates that table, calling each
+//! initializer function.
+//!
+//! # **WARNING!!*
+//! The environment that a static initializer function runs in is highly
+//! constrained. There are **many** restrictions on what static initializers
+//! can safely do. Static initializer functions **MUST NOT** do any of the
+//! following (this list is not comprehensive):
+//! * touch any other static field that is used by a different static
+//!   initializer, because the order that static initializers run in
+//!   is not defined.
+//! * call `LoadLibrary` or any other function that acquires the DLL
+//!   loader lock.
+//! * call any Rust function or CRT function that touches any static
+//!   (global) state.
 
 macro_rules! compat_fn {
     ($module:literal: $(
         $(#[$meta:meta])*
-        pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $body:block
+        pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $fallback_body:block
     )*) => ($(
         $(#[$meta])*
         pub mod $symbol {
             #[allow(unused_imports)]
             use super::*;
-            use crate::sync::atomic::{AtomicUsize, Ordering};
             use crate::mem;
 
             type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
 
-            static PTR: AtomicUsize = AtomicUsize::new(0);
-
-            #[allow(unused_variables)]
-            unsafe extern "system" fn fallback($($argname: $argtype),*) -> $rettype $body
-
-            /// This address is stored in `PTR` to incidate an unavailable API.
-            ///
-            /// This way, call() will end up calling fallback() if it is unavailable.
-            ///
-            /// This is a `static` to avoid rustc duplicating `fn fallback()`
-            /// into both load() and is_available(), which would break
-            /// is_available()'s comparison. By using the same static variable
-            /// in both places, they'll refer to the same (copy of the)
-            /// function.
+            /// Points to the DLL import, or the fallback function.
             ///
-            /// LLVM merging the address of fallback with other functions
-            /// (because of unnamed_addr) is fine, since it's only compared to
-            /// an address from GetProcAddress from an external dll.
-            static FALLBACK: F = fallback;
+            /// This static can be an ordinary, unsynchronized, mutable static because
+            /// we guarantee that all of the writes finish during CRT initialization,
+            /// and all of the reads occur after CRT initialization.
+            static mut PTR: Option<F> = None;
 
-            #[cold]
-            fn load() -> usize {
-                // There is no locking here. It's okay if this is executed by multiple threads in
-                // parallel. `lookup` will result in the same value, and it's okay if they overwrite
-                // eachothers result as long as they do so atomically. We don't need any guarantees
-                // about memory ordering, as this involves just a single atomic variable which is
-                // not used to protect or order anything else.
-                let addr = crate::sys::compat::lookup($module, stringify!($symbol))
-                    .unwrap_or(FALLBACK as usize);
-                PTR.store(addr, Ordering::Relaxed);
-                addr
-            }
+            /// This symbol is what allows the CRT to find the `init` function and call it.
+            /// It is marked `#[used]` because otherwise Rust would assume that it was not
+            /// used, and would remove it.
+            #[used]
+            #[link_section = ".CRT$XCU"]
+            static INIT_TABLE_ENTRY: fn() = init;
 
-            fn addr() -> usize {
-                match PTR.load(Ordering::Relaxed) {
-                    0 => load(),
-                    addr => addr,
+            fn init() {
+                // There is no locking here. This code is executed before main() is entered, and
+                // is guaranteed to be single-threaded.
+                //
+                // DO NOT do anything interesting or complicated in this function! DO NOT call
+                // any Rust functions or CRT functions, if those functions touch any global state,
+                // because this function runs during global initialization. For example, DO NOT
+                // do any dynamic allocation, don't call LoadLibrary, etc.
+                unsafe {
+                    let module_name: *const u8 = concat!($module, "\0").as_ptr();
+                    let symbol_name: *const u8 = concat!(stringify!($symbol), "\0").as_ptr();
+                    let module_handle = $crate::sys::c::GetModuleHandleA(module_name as *const i8);
+                    if !module_handle.is_null() {
+                        match $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8) as usize {
+                            0 => {}
+                            n => {
+                                PTR = Some(mem::transmute::<usize, F>(n));
+                            }
+                        }
+                    }
                 }
             }
 
             #[allow(dead_code)]
-            pub fn is_available() -> bool {
-                addr() != FALLBACK as usize
+            pub fn option() -> Option<F> {
+                unsafe { PTR }
             }
 
+            #[allow(dead_code)]
             pub unsafe fn call($($argname: $argtype),*) -> $rettype {
-                mem::transmute::<usize, F>(addr())($($argname),*)
+                if let Some(ptr) = PTR {
+                    ptr($($argname),*)
+                } else {
+                    $fallback_body
+                }
             }
         }
 
diff --git a/library/std/src/sys/windows/thread_parker.rs b/library/std/src/sys/windows/thread_parker.rs
index 9e4c9aa0a51..4f59d4dd452 100644
--- a/library/std/src/sys/windows/thread_parker.rs
+++ b/library/std/src/sys/windows/thread_parker.rs
@@ -108,10 +108,10 @@ impl Parker {
             return;
         }
 
-        if c::WaitOnAddress::is_available() {
+        if let Some(wait_on_address) = c::WaitOnAddress::option() {
             loop {
                 // Wait for something to happen, assuming it's still set to PARKED.
-                c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, c::INFINITE);
+                wait_on_address(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, c::INFINITE);
                 // Change NOTIFIED=>EMPTY but leave PARKED alone.
                 if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Acquire).is_ok() {
                     // Actually woken up by unpark().
@@ -140,9 +140,9 @@ impl Parker {
             return;
         }
 
-        if c::WaitOnAddress::is_available() {
+        if let Some(wait_on_address) = c::WaitOnAddress::option() {
             // Wait for something to happen, assuming it's still set to PARKED.
-            c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, dur2timeout(timeout));
+            wait_on_address(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, dur2timeout(timeout));
             // Set the state back to EMPTY (from either PARKED or NOTIFIED).
             // Note that we don't just write EMPTY, but use swap() to also
             // include an acquire-ordered read to synchronize with unpark()'s
@@ -192,9 +192,9 @@ impl Parker {
         // purpose, to make sure every unpark() has a release-acquire ordering
         // with park().
         if self.state.swap(NOTIFIED, Release) == PARKED {
-            if c::WakeByAddressSingle::is_available() {
+            if let Some(wake_by_address_single) = c::WakeByAddressSingle::option() {
                 unsafe {
-                    c::WakeByAddressSingle(self.ptr());
+                    wake_by_address_single(self.ptr());
                 }
             } else {
                 // If we run NtReleaseKeyedEvent before the waiting thread runs