summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/alloc/tests/string.rs126
-rw-r--r--library/alloc/tests/vec.rs166
-rw-r--r--library/alloc/tests/vec_deque.rs161
-rw-r--r--library/core/src/alloc/layout.rs76
-rw-r--r--library/core/src/mem/valid_align.rs11
-rw-r--r--library/std/src/sys/windows/path.rs9
-rw-r--r--library/std/src/sys/windows/path/tests.rs29
7 files changed, 369 insertions, 209 deletions
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs
index 99d1296a4c9..b6836fdc88e 100644
--- a/library/alloc/tests/string.rs
+++ b/library/alloc/tests/string.rs
@@ -693,6 +693,12 @@ fn test_try_reserve() {
     const MAX_CAP: usize = isize::MAX as usize;
     const MAX_USIZE: usize = usize::MAX;
 
+    // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+    // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+    // Any platform that succeeds for these requests is technically broken with
+    // ptr::offset because LLVM is the worst.
+    let guards_against_isize = usize::BITS < 64;
+
     {
         // Note: basic stuff is checked by test_reserve
         let mut empty_string: String = String::new();
@@ -706,19 +712,35 @@ fn test_try_reserve() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        // Check isize::MAX + 1 does count as overflow
-        assert_matches!(
-            empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        // Check usize::MAX does count as overflow
-        assert_matches!(
-            empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            // Check isize::MAX + 1 does count as overflow
+            assert_matches!(
+                empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            // Check usize::MAX does count as overflow
+            assert_matches!(
+                empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            // Check isize::MAX + 1 is an OOM
+            assert_matches!(
+                empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+
+            // Check usize::MAX is an OOM
+            assert_matches!(
+                empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -731,13 +753,19 @@ fn test_try_reserve() {
         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should always overflow in the add-to-len
         assert_matches!(
             ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -757,6 +785,8 @@ fn test_try_reserve_exact() {
     const MAX_CAP: usize = isize::MAX as usize;
     const MAX_USIZE: usize = usize::MAX;
 
+    let guards_against_isize = usize::BITS < 64;
+
     {
         let mut empty_string: String = String::new();
 
@@ -769,17 +799,31 @@ fn test_try_reserve_exact() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        assert_matches!(
-            empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        assert_matches!(
-            empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -795,13 +839,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
             Err(CapacityOverflow),
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index d94da8f5f5a..b797e237535 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1527,6 +1527,12 @@ fn test_try_reserve() {
     const MAX_CAP: usize = isize::MAX as usize;
     const MAX_USIZE: usize = usize::MAX;
 
+    // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+    // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+    // Any platform that succeeds for these requests is technically broken with
+    // ptr::offset because LLVM is the worst.
+    let guards_against_isize = usize::BITS < 64;
+
     {
         // Note: basic stuff is checked by test_reserve
         let mut empty_bytes: Vec<u8> = Vec::new();
@@ -1540,19 +1546,35 @@ fn test_try_reserve() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        // Check isize::MAX + 1 does count as overflow
-        assert_matches!(
-            empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        // Check usize::MAX does count as overflow
-        assert_matches!(
-            empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            // Check isize::MAX + 1 does count as overflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            // Check usize::MAX does count as overflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            // Check isize::MAX + 1 is an OOM
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+
+            // Check usize::MAX is an OOM
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -1565,13 +1587,19 @@ fn test_try_reserve() {
         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should always overflow in the add-to-len
         assert_matches!(
             ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1592,13 +1620,19 @@ fn test_try_reserve() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should fail in the mul-by-size
         assert_matches!(
             ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1618,6 +1652,8 @@ fn test_try_reserve_exact() {
     const MAX_CAP: usize = isize::MAX as usize;
     const MAX_USIZE: usize = usize::MAX;
 
+    let guards_against_isize = size_of::<usize>() < 8;
+
     {
         let mut empty_bytes: Vec<u8> = Vec::new();
 
@@ -1630,17 +1666,31 @@ fn test_try_reserve_exact() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        assert_matches!(
-            empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        assert_matches!(
-            empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -1656,13 +1706,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
             Err(CapacityOverflow),
@@ -1683,13 +1739,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
             Err(CapacityOverflow),
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index 019d73c0b16..89cc7f905be 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -2,6 +2,7 @@ use std::assert_matches::assert_matches;
 use std::collections::TryReserveErrorKind::*;
 use std::collections::{vec_deque::Drain, VecDeque};
 use std::fmt::Debug;
+use std::mem::size_of;
 use std::ops::Bound::*;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 
@@ -1160,6 +1161,12 @@ fn test_try_reserve() {
     const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
     const MAX_USIZE: usize = usize::MAX;
 
+    // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+    // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+    // Any platform that succeeds for these requests is technically broken with
+    // ptr::offset because LLVM is the worst.
+    let guards_against_isize = size_of::<usize>() < 8;
+
     {
         // Note: basic stuff is checked by test_reserve
         let mut empty_bytes: VecDeque<u8> = VecDeque::new();
@@ -1173,19 +1180,31 @@ fn test_try_reserve() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        // Check isize::MAX + 1 does count as overflow
-        assert_matches!(
-            empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        // Check usize::MAX does count as overflow
-        assert_matches!(
-            empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            // Check isize::MAX + 1 does count as overflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            // Check usize::MAX does count as overflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            // Check isize::MAX is an OOM
+            // VecDeque starts with capacity 7, always adds 1 to the capacity
+            // and also rounds the number to next power of 2 so this is the
+            // furthest we can go without triggering CapacityOverflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -1198,13 +1217,19 @@ fn test_try_reserve() {
         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should always overflow in the add-to-len
         assert_matches!(
             ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1225,13 +1250,19 @@ fn test_try_reserve() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should fail in the mul-by-size
         assert_matches!(
             ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1251,6 +1282,8 @@ fn test_try_reserve_exact() {
     const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
     const MAX_USIZE: usize = usize::MAX;
 
+    let guards_against_isize = size_of::<usize>() < 8;
+
     {
         let mut empty_bytes: VecDeque<u8> = VecDeque::new();
 
@@ -1263,17 +1296,29 @@ fn test_try_reserve_exact() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        assert_matches!(
-            empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        assert_matches!(
-            empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            // Check isize::MAX is an OOM
+            // VecDeque starts with capacity 7, always adds 1 to the capacity
+            // and also rounds the number to next power of 2 so this is the
+            // furthest we can go without triggering CapacityOverflow
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -1289,13 +1334,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
             Err(CapacityOverflow),
@@ -1316,13 +1367,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
             Err(CapacityOverflow),
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 59ebe5fbe02..2f378836cbb 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -1,9 +1,3 @@
-// Seemingly inconsequential code changes to this file can lead to measurable
-// performance impact on compilation times, due at least in part to the fact
-// that the layout code gets called from many instantiations of the various
-// collections, resulting in having to optimize down excess IR multiple times.
-// Your performance intuition is useless. Run perf.
-
 use crate::cmp;
 use crate::fmt;
 use crate::mem::{self, ValidAlign};
@@ -58,8 +52,8 @@ impl Layout {
     /// * `align` must be a power of two,
     ///
     /// * `size`, when rounded up to the nearest multiple of `align`,
-    ///    must not overflow isize (i.e., the rounded value must be
-    ///    less than or equal to `isize::MAX`).
+    ///    must not overflow (i.e., the rounded value must be less than
+    ///    or equal to `usize::MAX`).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
     #[inline]
@@ -68,13 +62,6 @@ impl Layout {
             return Err(LayoutError);
         }
 
-        // SAFETY: just checked that align is a power of two.
-        Layout::from_size_valid_align(size, unsafe { ValidAlign::new_unchecked(align) })
-    }
-
-    /// Internal helper constructor to skip revalidating alignment validity.
-    #[inline]
-    const fn from_size_valid_align(size: usize, align: ValidAlign) -> Result<Self, LayoutError> {
         // (power-of-two implies align != 0.)
 
         // Rounded up size is:
@@ -89,12 +76,13 @@ impl Layout {
         //
         // Above implies that checking for summation overflow is both
         // necessary and sufficient.
-        if size > isize::MAX as usize - (align.as_nonzero().get() - 1) {
+        if size > usize::MAX - (align - 1) {
             return Err(LayoutError);
         }
 
-        // SAFETY: Layout::size invariants checked above.
-        Ok(Layout { size, align })
+        // SAFETY: the conditions for `from_size_align_unchecked` have been
+        // checked above.
+        unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
     }
 
     /// Creates a layout, bypassing all checks.
@@ -108,8 +96,8 @@ impl Layout {
     #[must_use]
     #[inline]
     pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
-        // SAFETY: the caller is required to uphold the preconditions.
-        unsafe { Layout { size, align: ValidAlign::new_unchecked(align) } }
+        // SAFETY: the caller must ensure that `align` is a power of two.
+        Layout { size, align: unsafe { ValidAlign::new_unchecked(align) } }
     }
 
     /// The minimum size in bytes for a memory block of this layout.
@@ -138,9 +126,10 @@ impl Layout {
     #[inline]
     pub const fn new<T>() -> Self {
         let (size, align) = size_align::<T>();
-        // SAFETY: if the type is instantiated, rustc already ensures that its
-        // layout is valid. Use the unchecked constructor to avoid inserting a
-        // panicking codepath that needs to be optimized out.
+        // SAFETY: the align is guaranteed by Rust to be a power of two and
+        // the size+align combo is guaranteed to fit in our address space. As a
+        // result use the unchecked constructor here to avoid inserting code
+        // that panics if it isn't optimized well enough.
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }
 
@@ -152,6 +141,7 @@ impl Layout {
     #[inline]
     pub fn for_value<T: ?Sized>(t: &T) -> Self {
         let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
+        debug_assert!(Layout::from_size_align(size, align).is_ok());
         // SAFETY: see rationale in `new` for why this is using the unsafe variant
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }
@@ -186,6 +176,7 @@ impl Layout {
     pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
         // SAFETY: we pass along the prerequisites of these functions to the caller
         let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) };
+        debug_assert!(Layout::from_size_align(size, align).is_ok());
         // SAFETY: see rationale in `new` for why this is using the unsafe variant
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }
@@ -285,11 +276,12 @@ impl Layout {
         let pad = self.padding_needed_for(self.align());
         // This cannot overflow. Quoting from the invariant of Layout:
         // > `size`, when rounded up to the nearest multiple of `align`,
-        // > must not overflow isize (i.e., the rounded value must be
-        // > less than or equal to `isize::MAX`)
+        // > must not overflow (i.e., the rounded value must be less than
+        // > `usize::MAX`)
         let new_size = self.size() + pad;
 
-        // SAFETY: padded size is guaranteed to not exceed `isize::MAX`.
+        // SAFETY: self.align is already known to be valid and new_size has been
+        // padded already.
         unsafe { Layout::from_size_align_unchecked(new_size, self.align()) }
     }
 
@@ -306,13 +298,14 @@ impl Layout {
     pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
         // This cannot overflow. Quoting from the invariant of Layout:
         // > `size`, when rounded up to the nearest multiple of `align`,
-        // > must not overflow isize (i.e., the rounded value must be
-        // > less than or equal to `isize::MAX`)
+        // > must not overflow (i.e., the rounded value must be less than
+        // > `usize::MAX`)
         let padded_size = self.size() + self.padding_needed_for(self.align());
         let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
 
-        // The safe constructor is called here to enforce the isize size limit.
-        Layout::from_size_valid_align(alloc_size, self.align).map(|layout| (layout, padded_size))
+        // SAFETY: self.align is already known to be valid and alloc_size has been
+        // padded already.
+        unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -363,14 +356,13 @@ impl Layout {
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[inline]
     pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
-        let new_align = cmp::max(self.align, next.align);
+        let new_align = cmp::max(self.align(), next.align());
         let pad = self.padding_needed_for(next.align());
 
         let offset = self.size().checked_add(pad).ok_or(LayoutError)?;
         let new_size = offset.checked_add(next.size()).ok_or(LayoutError)?;
 
-        // The safe constructor is called here to enforce the isize size limit.
-        let layout = Layout::from_size_valid_align(new_size, new_align)?;
+        let layout = Layout::from_size_align(new_size, new_align)?;
         Ok((layout, offset))
     }
 
@@ -390,8 +382,7 @@ impl Layout {
     #[inline]
     pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
         let size = self.size().checked_mul(n).ok_or(LayoutError)?;
-        // The safe constructor is called here to enforce the isize size limit.
-        Layout::from_size_valid_align(size, self.align)
+        Layout::from_size_align(size, self.align())
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -404,8 +395,7 @@ impl Layout {
     #[inline]
     pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
         let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
-        // The safe constructor is called here to enforce the isize size limit.
-        Layout::from_size_valid_align(new_size, self.align)
+        Layout::from_size_align(new_size, self.align())
     }
 
     /// Creates a layout describing the record for a `[T; n]`.
@@ -415,8 +405,16 @@ impl Layout {
     #[inline]
     pub fn array<T>(n: usize) -> Result<Self, LayoutError> {
         let array_size = mem::size_of::<T>().checked_mul(n).ok_or(LayoutError)?;
-        // The safe constructor is called here to enforce the isize size limit.
-        Layout::from_size_valid_align(array_size, ValidAlign::of::<T>())
+
+        // SAFETY:
+        // - Size: `array_size` cannot be too big because `size_of::<T>()` must
+        //   be a multiple of `align_of::<T>()`. Therefore, `array_size`
+        //   rounded up to the nearest multiple of `align_of::<T>()` is just
+        //   `array_size`. And `array_size` cannot be too big because it was
+        //   just checked by the `checked_mul()`.
+        // - Alignment: `align_of::<T>()` will always give an acceptable
+        //   (non-zero, power of two) alignment.
+        Ok(unsafe { Layout::from_size_align_unchecked(array_size, mem::align_of::<T>()) })
     }
 }
 
diff --git a/library/core/src/mem/valid_align.rs b/library/core/src/mem/valid_align.rs
index 4ce6d13cf90..fcfa95120df 100644
--- a/library/core/src/mem/valid_align.rs
+++ b/library/core/src/mem/valid_align.rs
@@ -1,5 +1,4 @@
 use crate::convert::TryFrom;
-use crate::intrinsics::assert_unsafe_precondition;
 use crate::num::NonZeroUsize;
 use crate::{cmp, fmt, hash, mem, num};
 
@@ -27,8 +26,7 @@ impl ValidAlign {
     /// It must *not* be zero.
     #[inline]
     pub(crate) const unsafe fn new_unchecked(align: usize) -> Self {
-        // SAFETY: Precondition passed to the caller.
-        unsafe { assert_unsafe_precondition!(align.is_power_of_two()) };
+        debug_assert!(align.is_power_of_two());
 
         // SAFETY: By precondition, this must be a power of two, and
         // our variants encompass all possible powers of two.
@@ -48,13 +46,6 @@ impl ValidAlign {
     pub(crate) fn log2(self) -> u32 {
         self.as_nonzero().trailing_zeros()
     }
-
-    /// Returns the alignment for a type.
-    #[inline]
-    pub(crate) fn of<T>() -> Self {
-        // SAFETY: rustc ensures that type alignment is always a power of two.
-        unsafe { ValidAlign::new_unchecked(mem::align_of::<T>()) }
-    }
 }
 
 impl fmt::Debug for ValidAlign {
diff --git a/library/std/src/sys/windows/path.rs b/library/std/src/sys/windows/path.rs
index a0f82207099..beeca1917a9 100644
--- a/library/std/src/sys/windows/path.rs
+++ b/library/std/src/sys/windows/path.rs
@@ -198,14 +198,7 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
 
     match path.bytes().iter().position(|&x| separator(x)) {
         Some(separator_start) => {
-            let mut separator_end = separator_start + 1;
-
-            // a series of multiple separator characters is treated as a single separator,
-            // except in verbatim paths
-            while !verbatim && separator_end < path.len() && separator(path.bytes()[separator_end])
-            {
-                separator_end += 1;
-            }
+            let separator_end = separator_start + 1;
 
             let component = &path.bytes()[..separator_start];
 
diff --git a/library/std/src/sys/windows/path/tests.rs b/library/std/src/sys/windows/path/tests.rs
index 2f7ec433bf2..6eab38cabfd 100644
--- a/library/std/src/sys/windows/path/tests.rs
+++ b/library/std/src/sys/windows/path/tests.rs
@@ -31,16 +31,6 @@ fn test_parse_next_component() {
         parse_next_component(OsStr::new(r"servershare"), false),
         (OsStr::new(r"servershare"), OsStr::new(""))
     );
-
-    assert_eq!(
-        parse_next_component(OsStr::new(r"server/\//\/\\\\/////\/share"), false),
-        (OsStr::new(r"server"), OsStr::new(r"share"))
-    );
-
-    assert_eq!(
-        parse_next_component(OsStr::new(r"server\\\\\\\\\\\\\\share"), true),
-        (OsStr::new(r"server"), OsStr::new(r"\\\\\\\\\\\\\share"))
-    );
 }
 
 #[test]
@@ -126,3 +116,22 @@ fn test_windows_prefix_components() {
     assert_eq!(drive.as_os_str(), OsStr::new("C:"));
     assert_eq!(components.as_path(), Path::new(""));
 }
+
+/// See #101358.
+///
+/// Note that the exact behaviour here may change in the future.
+/// In which case this test will need to adjusted.
+#[test]
+fn broken_unc_path() {
+    use crate::path::Component;
+
+    let mut components = Path::new(r"\\foo\\bar\\").components();
+    assert_eq!(components.next(), Some(Component::RootDir));
+    assert_eq!(components.next(), Some(Component::Normal("foo".as_ref())));
+    assert_eq!(components.next(), Some(Component::Normal("bar".as_ref())));
+
+    let mut components = Path::new("//foo//bar//").components();
+    assert_eq!(components.next(), Some(Component::RootDir));
+    assert_eq!(components.next(), Some(Component::Normal("foo".as_ref())));
+    assert_eq!(components.next(), Some(Component::Normal("bar".as_ref())));
+}