about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-09-06 21:47:58 +0000
committerbors <bors@rust-lang.org>2025-09-06 21:47:58 +0000
commit76863e340416e7f21955bdaf0ae9728eb51f5671 (patch)
tree8edfe55e194edfdbc392461ef54e097fa55a2752
parent1ed3cd7030718935a5c5e5c8f6581f36d8be179f (diff)
parentf338542c4264cda116c02101e22f3659c420ea7f (diff)
downloadrust-76863e340416e7f21955bdaf0ae9728eb51f5671.tar.gz
rust-76863e340416e7f21955bdaf0ae9728eb51f5671.zip
Auto merge of #146282 - tgross35:rollup-0n5tjnm, r=tgross35
Rollup of 5 pull requests

Successful merges:

 - rust-lang/rust#139524 (Add socket extensions for cygwin)
 - rust-lang/rust#145940 (single buffer for exponent fmt of integers)
 - rust-lang/rust#146206 (identity uses are ok, even if there are no defining uses)
 - rust-lang/rust#146272 (Update comment for `-Werror` on LLVM builds)
 - rust-lang/rust#146280 (Make `LetChainsPolicy` public for rustfmt usage)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs11
-rw-r--r--compiler/rustc_llvm/build.rs8
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--library/core/src/fmt/num.rs389
-rw-r--r--library/coretests/benches/fmt.rs24
-rw-r--r--library/std/src/os/cygwin/mod.rs1
-rw-r--r--library/std/src/os/cygwin/net.rs17
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/net/linux_ext/mod.rs4
-rw-r--r--library/std/src/os/net/mod.rs2
-rw-r--r--library/std/src/os/unix/net/addr.rs8
-rw-r--r--library/std/src/os/unix/net/ancillary.rs31
-rw-r--r--library/std/src/os/unix/net/datagram.rs52
-rw-r--r--library/std/src/os/unix/net/mod.rs6
-rw-r--r--library/std/src/os/unix/net/stream.rs26
-rw-r--r--library/std/src/os/unix/net/tests.rs27
-rw-r--r--library/std/src/sys/net/connection/socket/unix.rs12
-rw-r--r--tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr29
-rw-r--r--tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr17
-rw-r--r--tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs15
21 files changed, 446 insertions, 239 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
index 72615cb33b3..95c5366a6c8 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
@@ -503,7 +503,16 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
     let mut errors = Vec::new();
     for &(key, hidden_type) in opaque_types {
         let Some(expected) = get_concrete_opaque_type(concrete_opaque_types, key.def_id) else {
-            assert!(tcx.use_typing_mode_borrowck(), "non-defining use in defining scope");
+            if !tcx.use_typing_mode_borrowck() {
+                if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
+                    && alias_ty.def_id == key.def_id.to_def_id()
+                    && alias_ty.args == key.args
+                {
+                    continue;
+                } else {
+                    unreachable!("non-defining use in defining scope");
+                }
+            }
             errors.push(DeferredOpaqueTypeError::NonDefiningUseInDefiningScope {
                 span: hidden_type.span,
                 opaque_type_key: key,
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index d01f79dcade..225ab8c846d 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -174,10 +174,10 @@ fn main() {
 
     // Prevent critical warnings when we're compiling from rust-lang/rust CI,
     // except on MSVC, as the compiler throws warnings that are only reported
-    // for this platform. See https://github.com/rust-lang/rust/pull/145031#issuecomment-3162677202
-    // FIXME(llvm22): It looks like the specific problem code has been removed
-    // in https://github.com/llvm/llvm-project/commit/e8fc808bf8e78a3c80d1f8e293a92677b92366dd,
-    // retry msvc once we bump our LLVM version.
+    // for this platform. See https://github.com/rust-lang/rust/pull/145031#issuecomment-3162677202.
+    // Moreover, LLVM generally guarantees warning-freedom only when building with Clang, as other
+    // compilers have too many false positives. This is typically the case for MSVC, which throws
+    // many false-positive warnings. We keep it excluded, for these reasons.
     if std::env::var_os("CI").is_some() && !target.contains("msvc") {
         cfg.warnings_into_errors(true);
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 9b09cbba7af..4c02547357e 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2742,7 +2742,7 @@ impl<'a> Parser<'a> {
     /// The specified `edition` in `let_chains_policy` should be that of the whole `if` construct,
     /// i.e. the same span we use to later decide whether the drop behaviour should be that of
     /// edition `..=2021` or that of `2024..`.
-    // Public because it is used in rustfmt forks such as https://github.com/tucant/rustfmt/blob/30c83df9e1db10007bdd16dafce8a86b404329b2/src/parse/macros/html.rs#L57 for custom if expressions.
+    // Public to use it for custom `if` expressions in rustfmt forks like https://github.com/tucant/rustfmt
     pub fn parse_expr_cond(
         &mut self,
         let_chains_policy: LetChainsPolicy,
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 15598f32429..3bbca622975 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -22,6 +22,8 @@ use std::{fmt, mem, slice};
 use attr_wrapper::{AttrWrapper, UsePreAttrPos};
 pub use diagnostics::AttemptLocalParseRecovery;
 pub(crate) use expr::ForbiddenLetReason;
+// Public to use it for custom `if` expressions in rustfmt forks like https://github.com/tucant/rustfmt
+pub use expr::LetChainsPolicy;
 pub(crate) use item::{FnContext, FnParseMode};
 pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
 pub use path::PathStyle;
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index 605ba42c541..253a7b7587e 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -3,7 +3,7 @@
 use crate::fmt::NumBuffer;
 use crate::mem::MaybeUninit;
 use crate::num::fmt as numfmt;
-use crate::{fmt, ptr, slice, str};
+use crate::{fmt, str};
 
 /// Formatting of integers with a non-decimal radix.
 macro_rules! radix_integer {
@@ -96,8 +96,8 @@ macro_rules! impl_Debug {
     };
 }
 
-// 2 digit decimal look up table
-static DEC_DIGITS_LUT: &[u8; 200] = b"\
+// The string of all two-digit numbers in range 00..99 is used as a lookup table.
+static DECIMAL_PAIRS: &[u8; 200] = b"\
       0001020304050607080910111213141516171819\
       2021222324252627282930313233343536373839\
       4041424344454647484950515253545556575859\
@@ -123,6 +123,9 @@ macro_rules! impl_Display {
 
         $(
         const _: () = {
+            assert!($Signed::MIN < 0, "need signed");
+            assert!($Unsigned::MIN == 0, "need unsigned");
+            assert!($Signed::BITS == $Unsigned::BITS, "need counterparts");
             assert!($Signed::BITS <= $T::BITS, "need lossless conversion");
             assert!($Unsigned::BITS <= $T::BITS, "need lossless conversion");
         };
@@ -207,10 +210,10 @@ macro_rules! impl_Display {
                     remain /= scale;
                     let pair1 = (quad / 100) as usize;
                     let pair2 = (quad % 100) as usize;
-                    buf[offset + 0].write(DEC_DIGITS_LUT[pair1 * 2 + 0]);
-                    buf[offset + 1].write(DEC_DIGITS_LUT[pair1 * 2 + 1]);
-                    buf[offset + 2].write(DEC_DIGITS_LUT[pair2 * 2 + 0]);
-                    buf[offset + 3].write(DEC_DIGITS_LUT[pair2 * 2 + 1]);
+                    buf[offset + 0].write(DECIMAL_PAIRS[pair1 * 2 + 0]);
+                    buf[offset + 1].write(DECIMAL_PAIRS[pair1 * 2 + 1]);
+                    buf[offset + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]);
+                    buf[offset + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]);
                 }
 
                 // Format per two digits from the lookup table.
@@ -225,8 +228,8 @@ macro_rules! impl_Display {
 
                     let pair = (remain % 100) as usize;
                     remain /= 100;
-                    buf[offset + 0].write(DEC_DIGITS_LUT[pair * 2 + 0]);
-                    buf[offset + 1].write(DEC_DIGITS_LUT[pair * 2 + 1]);
+                    buf[offset + 0].write(DECIMAL_PAIRS[pair * 2 + 0]);
+                    buf[offset + 1].write(DECIMAL_PAIRS[pair * 2 + 1]);
                 }
 
                 // Format the last remaining digit, if any.
@@ -242,7 +245,7 @@ macro_rules! impl_Display {
                     // Either the compiler sees that remain < 10, or it prevents
                     // a boundary check up next.
                     let last = (remain & 15) as usize;
-                    buf[offset].write(DEC_DIGITS_LUT[last * 2 + 1]);
+                    buf[offset].write(DECIMAL_PAIRS[last * 2 + 1]);
                     // not used: remain = 0;
                 }
 
@@ -335,7 +338,6 @@ macro_rules! impl_Display {
             }
         }
 
-
         )*
 
         #[cfg(feature = "optimize_for_size")]
@@ -374,178 +376,213 @@ macro_rules! impl_Display {
 
 macro_rules! impl_Exp {
     ($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => {
+        const _: () = assert!($T::MIN == 0, "need unsigned");
+
         fn $fmt_fn(
-            mut n: $T,
+            f: &mut fmt::Formatter<'_>,
+            n: $T,
             is_nonnegative: bool,
-            upper: bool,
-            f: &mut fmt::Formatter<'_>
+            letter_e: u8
         ) -> fmt::Result {
-            let (mut n, mut exponent, trailing_zeros, added_precision) = {
-                let mut exponent = 0;
-                // count and remove trailing decimal zeroes
-                while n % 10 == 0 && n >= 10 {
-                    n /= 10;
-                    exponent += 1;
-                }
-                let (added_precision, subtracted_precision) = match f.precision() {
-                    Some(fmt_prec) => {
-                        // number of decimal digits minus 1
-                        let mut tmp = n;
-                        let mut prec = 0;
-                        while tmp >= 10 {
-                            tmp /= 10;
-                            prec += 1;
-                        }
-                        (fmt_prec.saturating_sub(prec), prec.saturating_sub(fmt_prec))
+            debug_assert!(letter_e.is_ascii_alphabetic(), "single-byte character");
+
+            // Print the integer as a coefficient in range (-10, 10).
+            let mut exp = n.checked_ilog10().unwrap_or(0) as usize;
+            debug_assert!(n / (10 as $T).pow(exp as u32) < 10);
+
+            // Precisison is counted as the number of digits in the fraction.
+            let mut coef_prec = exp;
+            // Keep the digits as an integer (paired with its coef_prec count).
+            let mut coef = n;
+
+            // A Formatter may set the precision to a fixed number of decimals.
+            let more_prec = match f.precision() {
+                None => {
+                    // Omit any and all trailing zeroes.
+                    while coef_prec != 0 && coef % 10 == 0 {
+                        coef /= 10;
+                        coef_prec -= 1;
                     }
-                    None => (0, 0)
-                };
-                for _ in 1..subtracted_precision {
-                    n /= 10;
-                    exponent += 1;
-                }
-                if subtracted_precision != 0 {
-                    let rem = n % 10;
-                    n /= 10;
-                    exponent += 1;
-                    // round up last digit, round to even on a tie
-                    if rem > 5 || (rem == 5 && (n % 2 != 0 || subtracted_precision > 1 )) {
-                        n += 1;
-                        // if the digit is rounded to the next power
-                        // instead adjust the exponent
-                        if n.ilog10() > (n - 1).ilog10() {
-                            n /= 10;
-                            exponent += 1;
-                        }
+                    0
+                },
+
+                Some(fmt_prec) if fmt_prec >= coef_prec => {
+                    // Count the number of additional zeroes needed.
+                    fmt_prec - coef_prec
+                },
+
+                Some(fmt_prec) => {
+                    // Count the number of digits to drop.
+                    let less_prec = coef_prec - fmt_prec;
+                    assert!(less_prec > 0);
+                    // Scale down the coefficient/precision pair. For example,
+                    // coef 123456 gets coef_prec 5 (to make 1.23456). To format
+                    // the number with 2 decimals, i.e., fmt_prec 2, coef should
+                    // be scaled by 10⁵⁻²=1000 to get coef 123 with coef_prec 2.
+
+                    // SAFETY: Any precision less than coef_prec will cause a
+                    // power of ten below the coef value.
+                    let scale = unsafe {
+                        (10 as $T).checked_pow(less_prec as u32).unwrap_unchecked()
+                    };
+                    let floor = coef / scale;
+                    // Round half to even conform documentation.
+                    let over = coef % scale;
+                    let half = scale / 2;
+                    let round_up = if over < half {
+                        0
+                    } else if over > half {
+                        1
+                    } else {
+                        floor & 1 // round odd up to even
+                    };
+                    // Adding one to a scale down of at least 10 won't overflow.
+                    coef = floor + round_up;
+                    coef_prec = fmt_prec;
+
+                    // The round_up may have caused the coefficient to reach 10
+                    // (which is not permitted). For example, anything in range
+                    // [9.95, 10) becomes 10.0 when adjusted to precision 1.
+                    if round_up != 0 && coef.checked_ilog10().unwrap_or(0) as usize > coef_prec {
+                        debug_assert_eq!(coef, (10 as $T).pow(coef_prec as u32 + 1));
+                        coef /= 10; // drop one trailing zero
+                        exp += 1;   // one power of ten higher
                     }
-                }
-                (n, exponent, exponent, added_precision)
+                    0
+                },
             };
 
-            // Since `curr` always decreases by the number of digits copied, this means
-            // that `curr >= 0`.
-            let mut buf = [MaybeUninit::<u8>::uninit(); 40];
-            let mut curr = buf.len(); //index for buf
-            let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
-            let lut_ptr = DEC_DIGITS_LUT.as_ptr();
-
-            // decode 2 chars at a time
-            while n >= 100 {
-                let d1 = ((n % 100) as usize) << 1;
-                curr -= 2;
-                // SAFETY: `d1 <= 198`, so we can copy from `lut_ptr[d1..d1 + 2]` since
-                // `DEC_DIGITS_LUT` has a length of 200.
-                unsafe {
-                    ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
-                }
-                n /= 100;
-                exponent += 2;
-            }
-            // n is <= 99, so at most 2 chars long
-            let mut n = n as isize; // possibly reduce 64bit math
-            // decode second-to-last character
-            if n >= 10 {
-                curr -= 1;
-                // SAFETY: Safe since `40 > curr >= 0` (see comment)
-                unsafe {
-                    *buf_ptr.add(curr) = (n as u8 % 10_u8) + b'0';
+            // Allocate a text buffer with lazy initialization.
+            const MAX_DEC_N: usize = $T::MAX.ilog10() as usize + 1;
+            const MAX_COEF_LEN: usize = MAX_DEC_N + ".".len();
+            const MAX_TEXT_LEN: usize = MAX_COEF_LEN + "e99".len();
+            let mut buf = [MaybeUninit::<u8>::uninit(); MAX_TEXT_LEN];
+
+            // Encode the coefficient in buf[..coef_len].
+            let (lead_dec, coef_len) = if coef_prec == 0 && more_prec == 0 {
+                (coef, 1_usize) // single digit; no fraction
+            } else {
+                buf[1].write(b'.');
+                let fraction_range = 2..(2 + coef_prec);
+
+                // Consume the least-significant decimals from a working copy.
+                let mut remain = coef;
+                #[cfg(feature = "optimize_for_size")] {
+                    for i in fraction_range.clone().rev() {
+                        let digit = (remain % 10) as usize;
+                        remain /= 10;
+                        buf[i].write(b'0' + digit as u8);
+                    }
                 }
-                n /= 10;
-                exponent += 1;
-            }
-            // add decimal point iff >1 mantissa digit will be printed
-            if exponent != trailing_zeros || added_precision != 0 {
-                curr -= 1;
-                // SAFETY: Safe since `40 > curr >= 0`
-                unsafe {
-                    *buf_ptr.add(curr) = b'.';
+                #[cfg(not(feature = "optimize_for_size"))] {
+                    // Write digits per two at a time with a lookup table.
+                    for i in fraction_range.clone().skip(1).rev().step_by(2) {
+                        let pair = (remain % 100) as usize;
+                        remain /= 100;
+                        buf[i - 1].write(DECIMAL_PAIRS[pair * 2 + 0]);
+                        buf[i - 0].write(DECIMAL_PAIRS[pair * 2 + 1]);
+                    }
+                    // An odd number of digits leave one digit remaining.
+                    if coef_prec & 1 != 0 {
+                        let digit = (remain % 10) as usize;
+                        remain /= 10;
+                        buf[fraction_range.start].write(b'0' + digit as u8);
+                    }
                 }
-            }
 
-            // SAFETY: Safe since `40 > curr >= 0`
-            let buf_slice = unsafe {
-                // decode last character
-                curr -= 1;
-                *buf_ptr.add(curr) = (n as u8) + b'0';
-
-                let len = buf.len() - curr as usize;
-                slice::from_raw_parts(buf_ptr.add(curr), len)
+                (remain, fraction_range.end)
             };
-
-            // stores 'e' (or 'E') and the up to 2-digit exponent
-            let mut exp_buf = [MaybeUninit::<u8>::uninit(); 3];
-            let exp_ptr = MaybeUninit::slice_as_mut_ptr(&mut exp_buf);
-            // SAFETY: In either case, `exp_buf` is written within bounds and `exp_ptr[..len]`
-            // is contained within `exp_buf` since `len <= 3`.
-            let exp_slice = unsafe {
-                *exp_ptr.add(0) = if upper { b'E' } else { b'e' };
-                let len = if exponent < 10 {
-                    *exp_ptr.add(1) = (exponent as u8) + b'0';
-                    2
-                } else {
-                    let off = exponent << 1;
-                    ptr::copy_nonoverlapping(lut_ptr.add(off), exp_ptr.add(1), 2);
-                    3
-                };
-                slice::from_raw_parts(exp_ptr, len)
+            debug_assert!(lead_dec < 10);
+            debug_assert!(lead_dec != 0 || coef == 0, "significant digits only");
+            buf[0].write(b'0' + lead_dec as u8);
+
+            // SAFETY: The number of decimals is limited, captured by MAX.
+            unsafe { core::hint::assert_unchecked(coef_len <= MAX_COEF_LEN) }
+            // Encode the scale factor in buf[coef_len..text_len].
+            buf[coef_len].write(letter_e);
+            let text_len: usize = match exp {
+                ..10 => {
+                    buf[coef_len + 1].write(b'0' + exp as u8);
+                    coef_len + 2
+                },
+                10..100 => {
+                    #[cfg(feature = "optimize_for_size")] {
+                        buf[coef_len + 1].write(b'0' + (exp / 10) as u8);
+                        buf[coef_len + 2].write(b'0' + (exp % 10) as u8);
+                    }
+                    #[cfg(not(feature = "optimize_for_size"))] {
+                        buf[coef_len + 1].write(DECIMAL_PAIRS[exp * 2 + 0]);
+                        buf[coef_len + 2].write(DECIMAL_PAIRS[exp * 2 + 1]);
+                    }
+                    coef_len + 3
+                },
+                _ => {
+                    const { assert!($T::MAX.ilog10() < 100) };
+                    // SAFETY: A `u256::MAX` would get exponent 77.
+                    unsafe { core::hint::unreachable_unchecked() }
+                }
             };
-
-            let parts = &[
-                numfmt::Part::Copy(buf_slice),
-                numfmt::Part::Zero(added_precision),
-                numfmt::Part::Copy(exp_slice),
-            ];
-            let sign = if !is_nonnegative {
-                "-"
-            } else if f.sign_plus() {
-                "+"
+            // SAFETY: All bytes up until text_len have been set.
+            let text = unsafe { buf[..text_len].assume_init_ref() };
+
+            if more_prec == 0 {
+                // SAFETY: Text is set with ASCII exclusively: either a decimal,
+                // or a LETTER_E, or a dot. ASCII implies valid UTF-8.
+                let as_str = unsafe { str::from_utf8_unchecked(text) };
+                f.pad_integral(is_nonnegative, "", as_str)
             } else {
-                ""
-            };
-            let formatted = numfmt::Formatted { sign, parts };
-            // SAFETY: `buf_slice` and `exp_slice` contain only ASCII characters.
-            unsafe { f.pad_formatted_parts(&formatted) }
+                let parts = &[
+                    numfmt::Part::Copy(&text[..coef_len]),
+                    numfmt::Part::Zero(more_prec),
+                    numfmt::Part::Copy(&text[coef_len..]),
+                ];
+                let sign = if !is_nonnegative {
+                    "-"
+                } else if f.sign_plus() {
+                    "+"
+                } else {
+                    ""
+                };
+                // SAFETY: Text is set with ASCII exclusively: either a decimal,
+                // or a LETTER_E, or a dot. ASCII implies valid UTF-8.
+                unsafe { f.pad_formatted_parts(&numfmt::Formatted { sign, parts }) }
+            }
         }
 
         $(
-            #[stable(feature = "integer_exp_format", since = "1.42.0")]
-            impl fmt::LowerExp for $Signed {
-                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                    let is_nonnegative = *self >= 0;
-                    let n = if is_nonnegative {
-                        *self as $T
-                    } else {
-                        self.unsigned_abs() as $T
-                    };
-                    $fmt_fn(n, is_nonnegative, false, f)
-                }
+        const _: () = {
+            assert!($Signed::MIN < 0, "need signed");
+            assert!($Unsigned::MIN == 0, "need unsigned");
+            assert!($Signed::BITS == $Unsigned::BITS, "need counterparts");
+            assert!($Signed::BITS <= $T::BITS, "need lossless conversion");
+            assert!($Unsigned::BITS <= $T::BITS, "need lossless conversion");
+        };
+        #[stable(feature = "integer_exp_format", since = "1.42.0")]
+        impl fmt::LowerExp for $Signed {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                $fmt_fn(f, self.unsigned_abs() as $T, *self >= 0, b'e')
             }
-            #[stable(feature = "integer_exp_format", since = "1.42.0")]
-            impl fmt::LowerExp for $Unsigned {
-                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                    $fmt_fn(*self as $T, true, false, f)
-                }
-            })*
-
-        $(
-            #[stable(feature = "integer_exp_format", since = "1.42.0")]
-            impl fmt::UpperExp for $Signed {
-                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                    let is_nonnegative = *self >= 0;
-                    let n = if is_nonnegative {
-                        *self as $T
-                    } else {
-                        self.unsigned_abs() as $T
-                    };
-                    $fmt_fn(n, is_nonnegative, true, f)
-                }
+        }
+        #[stable(feature = "integer_exp_format", since = "1.42.0")]
+        impl fmt::LowerExp for $Unsigned {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                $fmt_fn(f, *self as $T, true, b'e')
             }
-            #[stable(feature = "integer_exp_format", since = "1.42.0")]
-            impl fmt::UpperExp for $Unsigned {
-                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                    $fmt_fn(*self as $T, true, true, f)
-                }
-            })*
+        }
+        #[stable(feature = "integer_exp_format", since = "1.42.0")]
+        impl fmt::UpperExp for $Signed {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                $fmt_fn(f, self.unsigned_abs() as $T, *self >= 0, b'E')
+            }
+        }
+        #[stable(feature = "integer_exp_format", since = "1.42.0")]
+        impl fmt::UpperExp for $Unsigned {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                $fmt_fn(f, *self as $T, true, b'E')
+            }
+        }
+        )*
+
     };
 }
 
@@ -658,10 +695,10 @@ impl u128 {
             remain /= 1_00_00;
             let pair1 = (quad / 100) as usize;
             let pair2 = (quad % 100) as usize;
-            buf[offset + 0].write(DEC_DIGITS_LUT[pair1 * 2 + 0]);
-            buf[offset + 1].write(DEC_DIGITS_LUT[pair1 * 2 + 1]);
-            buf[offset + 2].write(DEC_DIGITS_LUT[pair2 * 2 + 0]);
-            buf[offset + 3].write(DEC_DIGITS_LUT[pair2 * 2 + 1]);
+            buf[offset + 0].write(DECIMAL_PAIRS[pair1 * 2 + 0]);
+            buf[offset + 1].write(DECIMAL_PAIRS[pair1 * 2 + 1]);
+            buf[offset + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]);
+            buf[offset + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]);
         }
 
         // Format per two digits from the lookup table.
@@ -676,8 +713,8 @@ impl u128 {
 
             let pair = (remain % 100) as usize;
             remain /= 100;
-            buf[offset + 0].write(DEC_DIGITS_LUT[pair * 2 + 0]);
-            buf[offset + 1].write(DEC_DIGITS_LUT[pair * 2 + 1]);
+            buf[offset + 0].write(DECIMAL_PAIRS[pair * 2 + 0]);
+            buf[offset + 1].write(DECIMAL_PAIRS[pair * 2 + 1]);
         }
 
         // Format the last remaining digit, if any.
@@ -693,7 +730,7 @@ impl u128 {
             // Either the compiler sees that remain < 10, or it prevents
             // a boundary check up next.
             let last = (remain & 15) as usize;
-            buf[offset].write(DEC_DIGITS_LUT[last * 2 + 1]);
+            buf[offset].write(DECIMAL_PAIRS[last * 2 + 1]);
             // not used: remain = 0;
         }
         offset
@@ -792,10 +829,10 @@ fn enc_16lsd<const OFFSET: usize>(buf: &mut [MaybeUninit<u8>], n: u64) {
         remain /= 1_00_00;
         let pair1 = (quad / 100) as usize;
         let pair2 = (quad % 100) as usize;
-        buf[quad_index * 4 + OFFSET + 0].write(DEC_DIGITS_LUT[pair1 * 2 + 0]);
-        buf[quad_index * 4 + OFFSET + 1].write(DEC_DIGITS_LUT[pair1 * 2 + 1]);
-        buf[quad_index * 4 + OFFSET + 2].write(DEC_DIGITS_LUT[pair2 * 2 + 0]);
-        buf[quad_index * 4 + OFFSET + 3].write(DEC_DIGITS_LUT[pair2 * 2 + 1]);
+        buf[quad_index * 4 + OFFSET + 0].write(DECIMAL_PAIRS[pair1 * 2 + 0]);
+        buf[quad_index * 4 + OFFSET + 1].write(DECIMAL_PAIRS[pair1 * 2 + 1]);
+        buf[quad_index * 4 + OFFSET + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]);
+        buf[quad_index * 4 + OFFSET + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]);
     }
 }
 
diff --git a/library/coretests/benches/fmt.rs b/library/coretests/benches/fmt.rs
index f45b921b939..17549ab0f1c 100644
--- a/library/coretests/benches/fmt.rs
+++ b/library/coretests/benches/fmt.rs
@@ -342,3 +342,27 @@ fn write_i128_hex(bh: &mut Bencher) {
         black_box(&mut buf).clear();
     });
 }
+
+#[bench]
+fn write_i64_exp(bh: &mut Bencher) {
+    let mut buf = String::with_capacity(1024);
+    bh.iter(|| {
+        write!(black_box(&mut buf), "{:e}", black_box(0_i64)).unwrap();
+        write!(black_box(&mut buf), "{:e}", black_box(100_i64)).unwrap();
+        write!(black_box(&mut buf), "{:e}", black_box(-100_i64)).unwrap();
+        write!(black_box(&mut buf), "{:e}", black_box(1_i64 << 32)).unwrap();
+        black_box(&mut buf).clear();
+    });
+}
+
+#[bench]
+fn write_i128_exp(bh: &mut Bencher) {
+    let mut buf = String::with_capacity(1024);
+    bh.iter(|| {
+        write!(black_box(&mut buf), "{:e}", black_box(0_i128)).unwrap();
+        write!(black_box(&mut buf), "{:e}", black_box(100_i128)).unwrap();
+        write!(black_box(&mut buf), "{:e}", black_box(-100_i128)).unwrap();
+        write!(black_box(&mut buf), "{:e}", black_box(1_i128 << 64)).unwrap();
+        black_box(&mut buf).clear();
+    });
+}
diff --git a/library/std/src/os/cygwin/mod.rs b/library/std/src/os/cygwin/mod.rs
index 7f6d6a645c8..a295a07caac 100644
--- a/library/std/src/os/cygwin/mod.rs
+++ b/library/std/src/os/cygwin/mod.rs
@@ -1,4 +1,5 @@
 //! Cygwin-specific definitions
 #![stable(feature = "raw_ext", since = "1.1.0")]
 pub mod fs;
+pub mod net;
 pub(crate) mod raw;
diff --git a/library/std/src/os/cygwin/net.rs b/library/std/src/os/cygwin/net.rs
new file mode 100644
index 00000000000..0cccddb85d0
--- /dev/null
+++ b/library/std/src/os/cygwin/net.rs
@@ -0,0 +1,17 @@
+//! Cygwin-specific networking functionality.
+//!
+//! There are some limitations of Unix domain sockets on Cygwin:
+//! * The syscalls `accept` and `connect` need
+//! [handshake](https://inbox.sourceware.org/cygwin/Z_UERXFI1g-1v3p2@calimero.vinschen.de/T/#t).
+//! * Cannot bind to abstract addr.
+//! * Unbounded unix socket has an abstract local addr.
+//! * Doesn't support recvmsg with control data.
+
+#![stable(feature = "unix_socket_abstract", since = "1.70.0")]
+
+#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
+pub use crate::os::net::linux_ext::addr::SocketAddrExt;
+#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+pub use crate::os::net::linux_ext::socket::UnixSocketExt;
+#[stable(feature = "tcp_quickack", since = "1.89.0")]
+pub use crate::os::net::linux_ext::tcp::TcpStreamExt;
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index ab7734a7952..96d9bfae8ca 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -185,5 +185,5 @@ pub mod xous;
 #[cfg(any(unix, target_os = "hermit", target_os = "trusty", target_os = "wasi", doc))]
 pub mod fd;
 
-#[cfg(any(target_os = "linux", target_os = "android", doc))]
+#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))]
 mod net;
diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs
index 3c9afe35479..f3f3fdd258c 100644
--- a/library/std/src/os/net/linux_ext/mod.rs
+++ b/library/std/src/os/net/linux_ext/mod.rs
@@ -1,6 +1,6 @@
-//! Linux and Android-specific networking functionality.
+//! Linux, Android and Cygwin-specific networking functionality.
 
-#![doc(cfg(any(target_os = "linux", target_os = "android")))]
+#![doc(cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin")))]
 
 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
 pub(crate) mod addr;
diff --git a/library/std/src/os/net/mod.rs b/library/std/src/os/net/mod.rs
index b7046dd7c59..47e69b3a260 100644
--- a/library/std/src/os/net/mod.rs
+++ b/library/std/src/os/net/mod.rs
@@ -9,5 +9,5 @@
         all(target_vendor = "fortanix", target_env = "sgx")
     )
 )))]
-#[cfg(any(target_os = "linux", target_os = "android", doc))]
+#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))]
 pub(super) mod linux_ext;
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index fd6fe72dd24..25b95014e08 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -1,6 +1,6 @@
 use crate::bstr::ByteStr;
 use crate::ffi::OsStr;
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use crate::os::net::linux_ext;
 use crate::os::unix::ffi::OsStrExt;
 use crate::path::Path;
@@ -241,7 +241,7 @@ impl SocketAddr {
 
         // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
         if len == 0
-            || (cfg!(not(any(target_os = "linux", target_os = "android")))
+            || (cfg!(not(any(target_os = "linux", target_os = "android", target_os = "cygwin")))
                 && self.addr.sun_path[0] == 0)
         {
             AddressKind::Unnamed
@@ -256,8 +256,8 @@ impl SocketAddr {
 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
 impl Sealed for SocketAddr {}
 
-#[doc(cfg(any(target_os = "android", target_os = "linux")))]
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
 impl linux_ext::addr::SocketAddrExt for SocketAddr {
     fn as_abstract_name(&self) -> Option<&[u8]> {
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 36967fc3f98..d0984bdfb99 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -16,7 +16,8 @@ use crate::sys::net::Socket;
     not(target_os = "linux"),
     not(target_os = "android"),
     not(target_os = "netbsd"),
-    not(target_os = "freebsd")
+    not(target_os = "freebsd"),
+    not(target_os = "cygwin"),
 ))]
 #[allow(non_camel_case_types)]
 mod libc {
@@ -195,14 +196,15 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> {
     not(target_os = "android"),
     not(target_os = "linux"),
     not(target_os = "netbsd"),
-    not(target_os = "freebsd")
+    not(target_os = "freebsd"),
+    not(target_os = "cygwin"),
 ))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 #[derive(Clone)]
 pub struct SocketCred(());
 
 /// Unix credential.
-#[cfg(any(target_os = "android", target_os = "linux",))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 #[derive(Clone)]
 pub struct SocketCred(libc::ucred);
@@ -217,8 +219,8 @@ pub struct SocketCred(libc::sockcred);
 #[derive(Clone)]
 pub struct SocketCred(libc::sockcred2);
 
-#[doc(cfg(any(target_os = "android", target_os = "linux")))]
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 impl SocketCred {
     /// Creates a Unix credential struct.
     ///
@@ -407,7 +409,8 @@ impl<'a> Iterator for ScmRights<'a> {
     not(target_os = "android"),
     not(target_os = "linux"),
     not(target_os = "netbsd"),
-    not(target_os = "freebsd")
+    not(target_os = "freebsd"),
+    not(target_os = "cygwin"),
 ))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
@@ -415,7 +418,7 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
 /// This control message contains unix credentials.
 ///
 /// The level is equal to `SOL_SOCKET` and the type is equal to `SCM_CREDENTIALS` or `SCM_CREDS`.
-#[cfg(any(target_os = "android", target_os = "linux",))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>);
 
@@ -432,7 +435,8 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred>);
     target_os = "android",
     target_os = "linux",
     target_os = "netbsd",
-    target_os = "freebsd"
+    target_os = "freebsd",
+    target_os = "cygwin",
 ))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 impl<'a> Iterator for ScmCredentials<'a> {
@@ -460,7 +464,8 @@ pub enum AncillaryData<'a> {
         target_os = "android",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "freebsd"
+        target_os = "freebsd",
+        target_os = "cygwin",
     ))]
     ScmCredentials(ScmCredentials<'a>),
 }
@@ -489,7 +494,8 @@ impl<'a> AncillaryData<'a> {
         target_os = "android",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "freebsd"
+        target_os = "freebsd",
+        target_os = "cygwin",
     ))]
     unsafe fn as_credentials(data: &'a [u8]) -> Self {
         let ancillary_data_iter = AncillaryDataIter::new(data);
@@ -507,7 +513,7 @@ impl<'a> AncillaryData<'a> {
             match (*cmsg).cmsg_level {
                 libc::SOL_SOCKET => match (*cmsg).cmsg_type {
                     libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)),
-                    #[cfg(any(target_os = "android", target_os = "linux",))]
+                    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
                     libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)),
                     #[cfg(target_os = "freebsd")]
                     libc::SCM_CREDS2 => Ok(AncillaryData::as_credentials(data)),
@@ -729,7 +735,8 @@ impl<'a> SocketAncillary<'a> {
         target_os = "android",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "freebsd"
+        target_os = "freebsd",
+        target_os = "cygwin",
     ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn add_creds(&mut self, creds: &[SocketCred]) -> bool {
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 7735637c840..469bfbb0d83 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -14,9 +14,9 @@
 use libc::MSG_NOSIGNAL;
 
 use super::{SocketAddr, sockaddr_un};
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use crate::io::{IoSlice, IoSliceMut};
 use crate::net::Shutdown;
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
@@ -397,8 +397,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
     /// use std::io::IoSliceMut;
@@ -428,7 +434,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn recv_vectored_with_ancillary_from(
         &self,
@@ -447,8 +453,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
     /// use std::io::IoSliceMut;
@@ -478,7 +490,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn recv_vectored_with_ancillary(
         &self,
@@ -588,8 +600,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
     /// use std::io::IoSlice;
@@ -613,7 +631,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn send_vectored_with_ancillary_to<P: AsRef<Path>>(
         &self,
@@ -630,8 +648,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
     /// use std::io::IoSlice;
@@ -655,7 +679,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn send_vectored_with_ancillary(
         &self,
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index 6cd62303a53..94523d7d1e4 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -4,8 +4,8 @@
 #![stable(feature = "unix_socket", since = "1.10.0")]
 
 mod addr;
-#[doc(cfg(any(target_os = "android", target_os = "linux")))]
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 mod ancillary;
 mod datagram;
 mod listener;
@@ -27,7 +27,7 @@ mod ucred;
 
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub use self::addr::*;
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub use self::ancillary::*;
 #[stable(feature = "unix_socket", since = "1.10.0")]
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index 768fa77a5f8..ea4171a7d28 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -16,7 +16,7 @@ cfg_select! {
 }
 
 use super::{SocketAddr, sockaddr_un};
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
 #[cfg(any(
     target_os = "android",
@@ -508,8 +508,14 @@ impl UnixStream {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
     /// use std::io::IoSliceMut;
@@ -539,7 +545,7 @@ impl UnixStream {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn recv_vectored_with_ancillary(
         &self,
@@ -557,8 +563,14 @@ impl UnixStream {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixStream, SocketAncillary};
     /// use std::io::IoSlice;
@@ -582,7 +594,7 @@ impl UnixStream {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn send_vectored_with_ancillary(
         &self,
diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs
index 9a88687b1df..4666b5e3c6c 100644
--- a/library/std/src/os/unix/net/tests.rs
+++ b/library/std/src/os/unix/net/tests.rs
@@ -3,6 +3,8 @@ use crate::io::prelude::*;
 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
 #[cfg(target_os = "android")]
 use crate::os::android::net::{SocketAddrExt, UnixSocketExt};
+#[cfg(target_os = "cygwin")]
+use crate::os::cygwin::net::{SocketAddrExt, UnixSocketExt};
 #[cfg(target_os = "linux")]
 use crate::os::linux::net::{SocketAddrExt, UnixSocketExt};
 #[cfg(any(target_os = "android", target_os = "linux"))]
@@ -170,6 +172,7 @@ fn long_path() {
 #[test]
 #[cfg(not(target_os = "nto"))]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn timeouts() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -198,6 +201,7 @@ fn timeouts() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn test_read_timeout() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -218,6 +222,7 @@ fn test_read_timeout() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn test_read_with_timeout() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -246,6 +251,7 @@ fn test_read_with_timeout() {
 // when passed zero Durations
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn test_unix_stream_timeout_zero_duration() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -283,6 +289,7 @@ fn test_unix_datagram() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin autobinds an address
 fn test_unnamed_unix_datagram() {
     let dir = tmpdir();
     let path1 = dir.path().join("sock1");
@@ -326,6 +333,7 @@ fn test_unix_datagram_connect_to_recv_addr() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin autobinds an address
 fn test_connect_unix_datagram() {
     let dir = tmpdir();
     let path1 = dir.path().join("sock1");
@@ -425,8 +433,9 @@ fn abstract_namespace_not_allowed_connect() {
     assert!(UnixStream::connect("\0asdf").is_err());
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_stream_connect() {
     let msg1 = b"hello";
     let msg2 = b"world";
@@ -456,8 +465,9 @@ fn test_abstract_stream_connect() {
     thread.join().unwrap();
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_stream_iter() {
     let addr = or_panic!(SocketAddr::from_abstract_name(b"hidden"));
     let listener = or_panic!(UnixListener::bind_addr(&addr));
@@ -478,8 +488,9 @@ fn test_abstract_stream_iter() {
     thread.join().unwrap();
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_datagram_bind_send_to_addr() {
     let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns1"));
     let sock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
@@ -499,8 +510,9 @@ fn test_abstract_datagram_bind_send_to_addr() {
     assert_eq!(addr.as_abstract_name().unwrap(), b"ns1");
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_datagram_connect_addr() {
     let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns3"));
     let bsock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
@@ -524,7 +536,7 @@ fn test_abstract_datagram_connect_addr() {
     or_panic!(bsock2.recv_from(&mut buf));
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
 fn test_abstract_name_too_long() {
     match SocketAddr::from_abstract_name(
@@ -538,7 +550,7 @@ fn test_abstract_name_too_long() {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
 fn test_abstract_no_pathname_and_not_unnamed() {
     let name = b"local";
@@ -669,9 +681,10 @@ fn test_send_vectored_fds_unix_stream() {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin recvmsg doesn't support Unix sockets
 fn test_send_vectored_with_ancillary_to_unix_datagram() {
     fn getpid() -> libc::pid_t {
         unsafe { libc::getpid() }
diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs
index 8b5970d1494..8216f8d2fd5 100644
--- a/library/std/src/sys/net/connection/socket/unix.rs
+++ b/library/std/src/sys/net/connection/socket/unix.rs
@@ -361,7 +361,7 @@ impl Socket {
         self.recv_from_with_flags(buf, 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux"))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> {
         let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?;
         Ok(n as usize)
@@ -384,7 +384,7 @@ impl Socket {
         self.0.is_write_vectored()
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux"))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> {
         let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?;
         Ok(n as usize)
@@ -472,12 +472,12 @@ impl Socket {
         Ok(raw != 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn set_quickack(&self, quickack: bool) -> io::Result<()> {
         setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn quickack(&self) -> io::Result<bool> {
         let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?;
         Ok(raw != 0)
@@ -541,12 +541,12 @@ impl Socket {
         Ok(raw != 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
         setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn passcred(&self) -> io::Result<bool> {
         let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?;
         Ok(passcred != 0)
diff --git a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr
new file mode 100644
index 00000000000..ccbe2d3593c
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr
@@ -0,0 +1,29 @@
+error[E0277]: the trait bound `(): ReturnsSend` is not satisfied
+  --> $DIR/ice-issue-146191.rs:6:52
+   |
+LL | fn create_complex_future() -> impl Future<Output = impl ReturnsSend> {
+   |                                                    ^^^^^^^^^^^^^^^^ the trait `ReturnsSend` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/ice-issue-146191.rs:14:1
+   |
+LL | trait ReturnsSend {}
+   | ^^^^^^^^^^^^^^^^^
+note: required by a bound in an opaque type
+  --> $DIR/ice-issue-146191.rs:6:57
+   |
+LL | fn create_complex_future() -> impl Future<Output = impl ReturnsSend> {
+   |                                                         ^^^^^^^^^^^
+
+error[E0733]: recursion in an async block requires boxing
+  --> $DIR/ice-issue-146191.rs:8:5
+   |
+LL |     async { create_complex_future().await }
+   |     ^^^^^   ----------------------------- recursive call here
+   |
+   = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0733.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr
new file mode 100644
index 00000000000..e8b551c65fc
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed
+  --> $DIR/ice-issue-146191.rs:8:5
+   |
+LL |     async { create_complex_future().await }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error[E0282]: type annotations needed
+  --> $DIR/ice-issue-146191.rs:8:5
+   |
+LL |     async { create_complex_future().await }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs
new file mode 100644
index 00000000000..356f7d01eb9
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs
@@ -0,0 +1,15 @@
+//@ edition: 2024
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+
+fn create_complex_future() -> impl Future<Output = impl ReturnsSend> {
+    //[current]~^ ERROR the trait bound `(): ReturnsSend` is not satisfied
+    async { create_complex_future().await }
+    //[current]~^ ERROR recursion in an async block requires
+    //[next]~^^ ERROR type annotations needed
+    //[next]~| ERROR type annotations needed
+}
+
+trait ReturnsSend {}
+fn main() {}