From fa9a911a57eff5d2cd59eacbffb4e41bc721db2e Mon Sep 17 00:00:00 2001
From: joboet <jonasboettiger@icloud.com>
Date: Sat, 13 Jan 2024 20:10:00 +0100
Subject: [PATCH 1/2] libs: use `assert_unchecked` instead of intrinsic

---
 library/alloc/src/alloc.rs            | 6 +++---
 library/alloc/src/lib.rs              | 1 +
 library/alloc/src/raw_vec.rs          | 8 ++++----
 library/alloc/src/rc.rs               | 5 +++--
 library/alloc/src/vec/mod.rs          | 2 +-
 library/core/src/alloc/global.rs      | 2 +-
 library/core/src/lib.rs               | 1 +
 library/core/src/num/mod.rs           | 1 +
 library/core/src/num/uint_macros.rs   | 4 ++--
 library/core/src/slice/index.rs       | 2 +-
 library/core/src/slice/iter.rs        | 2 +-
 library/core/src/slice/iter/macros.rs | 4 ++--
 library/core/src/slice/mod.rs         | 5 +++--
 library/std/src/alloc.rs              | 6 +++---
 library/std/src/lib.rs                | 1 +
 15 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 1663aa84921..0b142939755 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -3,7 +3,7 @@
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
 #[cfg(not(test))]
-use core::intrinsics;
+use core::hint;
 
 #[cfg(not(test))]
 use core::ptr::{self, NonNull};
@@ -208,7 +208,7 @@ impl Global {
                 let new_size = new_layout.size();
 
                 // `realloc` probably checks for `new_size >= old_layout.size()` or something similar.
-                intrinsics::assume(new_size >= old_layout.size());
+                hint::assert_unchecked(new_size >= old_layout.size());
 
                 let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
                 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
@@ -299,7 +299,7 @@ unsafe impl Allocator for Global {
             // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller
             new_size if old_layout.align() == new_layout.align() => unsafe {
                 // `realloc` probably checks for `new_size <= old_layout.size()` or something similar.
-                intrinsics::assume(new_size <= old_layout.size());
+                hint::assert_unchecked(new_size <= old_layout.size());
 
                 let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
                 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 78629b39d34..02ecbe22b3e 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -129,6 +129,7 @@
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
 #![feature(hasher_prefixfree_extras)]
+#![feature(hint_assert_unchecked)]
 #![feature(inline_const)]
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 45e82240164..94e6924f41a 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -2,7 +2,7 @@
 
 use core::alloc::LayoutError;
 use core::cmp;
-use core::intrinsics;
+use core::hint;
 use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
 use core::ptr::{self, NonNull, Unique};
 use core::slice;
@@ -325,7 +325,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         }
         unsafe {
             // Inform the optimizer that the reservation has succeeded or wasn't needed
-            core::intrinsics::assume(!self.needs_to_grow(len, additional));
+            hint::assert_unchecked(!self.needs_to_grow(len, additional));
         }
         Ok(())
     }
@@ -363,7 +363,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         }
         unsafe {
             // Inform the optimizer that the reservation has succeeded or wasn't needed
-            core::intrinsics::assume(!self.needs_to_grow(len, additional));
+            hint::assert_unchecked(!self.needs_to_grow(len, additional));
         }
         Ok(())
     }
@@ -514,7 +514,7 @@ where
         debug_assert_eq!(old_layout.align(), new_layout.align());
         unsafe {
             // The allocator checks for alignment equality
-            intrinsics::assume(old_layout.align() == new_layout.align());
+            hint::assert_unchecked(old_layout.align() == new_layout.align());
             alloc.grow(ptr, old_layout, new_layout)
         }
     } else {
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 263b1449de1..1eab681e956 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -252,6 +252,7 @@ use core::cell::Cell;
 use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{Hash, Hasher};
+use core::hint;
 use core::intrinsics::abort;
 #[cfg(not(no_global_oom_handling))]
 use core::iter;
@@ -3268,7 +3269,7 @@ trait RcInnerPtr {
         // SAFETY: The reference count will never be zero when this is
         // called.
         unsafe {
-            core::intrinsics::assume(strong != 0);
+            hint::assert_unchecked(strong != 0);
         }
 
         let strong = strong.wrapping_add(1);
@@ -3301,7 +3302,7 @@ trait RcInnerPtr {
         // SAFETY: The reference count will never be zero when this is
         // called.
         unsafe {
-            core::intrinsics::assume(weak != 0);
+            hint::assert_unchecked(weak != 0);
         }
 
         let weak = weak.wrapping_add(1);
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 8aa0c6e7ed6..5504af28e88 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1993,7 +1993,7 @@ impl<T, A: Allocator> Vec<T, A> {
         } else {
             unsafe {
                 self.len -= 1;
-                core::intrinsics::assume(self.len < self.capacity());
+                core::hint::assert_unchecked(self.len < self.capacity());
                 Some(ptr::read(self.as_ptr().add(self.len())))
             }
         }
diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs
index c582111701a..a1fff6707bd 100644
--- a/library/core/src/alloc/global.rs
+++ b/library/core/src/alloc/global.rs
@@ -110,7 +110,7 @@ use crate::ptr;
 ///   ```rust,ignore (unsound and has placeholders)
 ///   drop(Box::new(42));
 ///   let number_of_heap_allocs = /* call private allocator API */;
-///   unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); }
+///   unsafe { std::hint::assert_unchecked(number_of_heap_allocs > 0); }
 ///   ```
 ///
 ///   Note that the optimizations mentioned above are not the only
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 1a8f245c8be..d0f89efa518 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -131,6 +131,7 @@
 #![feature(const_fmt_arguments_new)]
 #![feature(const_hash)]
 #![feature(const_heap)]
+#![feature(const_hint_assert_unchecked)]
 #![feature(const_index_range_slice_index)]
 #![feature(const_int_unchecked_arith)]
 #![feature(const_intrinsic_forget)]
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 695e87aaabf..2e683592b46 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -3,6 +3,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::ascii;
+use crate::hint;
 use crate::intrinsics;
 use crate::mem;
 use crate::ops::{Add, Mul, Sub};
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 11a53aaf122..62d6015fafe 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2036,8 +2036,8 @@ macro_rules! uint_impl {
             // SAFETY: the result is positive and fits in an integer with half as many bits.
             // Inform the optimizer about it.
             unsafe {
-                intrinsics::assume(0 < res);
-                intrinsics::assume(res < 1 << (Self::BITS / 2));
+                hint::assert_unchecked(0 < res);
+                hint::assert_unchecked(res < 1 << (Self::BITS / 2));
             }
 
             res
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 373b4aee47a..fb9be396eab 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -234,7 +234,7 @@ unsafe impl<T> SliceIndex<[T]> for usize {
         // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
         // so the call to `add` is safe.
         unsafe {
-            crate::intrinsics::assume(self < slice.len());
+            crate::hint::assert_unchecked(self < slice.len());
             slice.as_ptr().add(self)
         }
     }
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 3d58afd26ea..e1d19fef35f 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -6,7 +6,7 @@ mod macros;
 use crate::cmp;
 use crate::cmp::Ordering;
 use crate::fmt;
-use crate::intrinsics::assume;
+use crate::hint::assert_unchecked;
 use crate::iter::{
     FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, UncheckedIterator,
 };
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 95bcd123b82..fc6af45fb90 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -338,7 +338,7 @@ macro_rules! iterator {
                     if predicate(x) {
                         // SAFETY: we are guaranteed to be in bounds by the loop invariant:
                         // when `i >= n`, `self.next()` returns `None` and the loop breaks.
-                        unsafe { assume(i < n) };
+                        unsafe { assert_unchecked(i < n) };
                         return Some(i);
                     }
                     i += 1;
@@ -361,7 +361,7 @@ macro_rules! iterator {
                     if predicate(x) {
                         // SAFETY: `i` must be lower than `n` since it starts at `n`
                         // and is only decreasing.
-                        unsafe { assume(i < n) };
+                        unsafe { assert_unchecked(i < n) };
                         return Some(i);
                     }
                 }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 5edc89e4cb5..e971f933570 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -8,6 +8,7 @@
 
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::fmt;
+use crate::hint;
 use crate::intrinsics::exact_div;
 use crate::mem::{self, SizedTypeProperties};
 use crate::num::NonZeroUsize;
@@ -2850,7 +2851,7 @@ impl<T> [T] {
             right = if cmp == Greater { mid } else { right };
             if cmp == Equal {
                 // SAFETY: same as the `get_unchecked` above
-                unsafe { crate::intrinsics::assume(mid < self.len()) };
+                unsafe { hint::assert_unchecked(mid < self.len()) };
                 return Ok(mid);
             }
 
@@ -2859,7 +2860,7 @@ impl<T> [T] {
 
         // SAFETY: directly true from the overall invariant.
         // Note that this is `<=`, unlike the assume in the `Ok` path.
-        unsafe { crate::intrinsics::assume(left <= self.len()) };
+        unsafe { hint::assert_unchecked(left <= self.len()) };
         Err(left)
     }
 
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index bb786bd59dc..a834b36697c 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -56,7 +56,7 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
-use core::intrinsics;
+use core::hint;
 use core::ptr::NonNull;
 use core::sync::atomic::{AtomicPtr, Ordering};
 use core::{mem, ptr};
@@ -172,7 +172,7 @@ impl System {
                 let new_size = new_layout.size();
 
                 // `realloc` probably checks for `new_size >= old_layout.size()` or something similar.
-                intrinsics::assume(new_size >= old_layout.size());
+                hint::assert_unchecked(new_size >= old_layout.size());
 
                 let raw_ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size);
                 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
@@ -264,7 +264,7 @@ unsafe impl Allocator for System {
             // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller
             new_size if old_layout.align() == new_layout.align() => unsafe {
                 // `realloc` probably checks for `new_size <= old_layout.size()` or something similar.
-                intrinsics::assume(new_size <= old_layout.size());
+                hint::assert_unchecked(new_size <= old_layout.size());
 
                 let raw_ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size);
                 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 7a8d9d0ceec..29ef26113ce 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -325,6 +325,7 @@
 #![feature(float_next_up_down)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
+#![feature(hint_assert_unchecked)]
 #![feature(ip)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array)]

From 638439a4404d9ef2da4027585134487875787e1d Mon Sep 17 00:00:00 2001
From: joboet <jonasboettiger@icloud.com>
Date: Mon, 22 Jan 2024 15:46:32 +0100
Subject: [PATCH 2/2] update codegen tests

---
 tests/codegen/vec-reserve-extend.rs | 2 ++
 tests/codegen/vec_pop_push_noop.rs  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/tests/codegen/vec-reserve-extend.rs b/tests/codegen/vec-reserve-extend.rs
index d95220104c2..395373ff4f1 100644
--- a/tests/codegen/vec-reserve-extend.rs
+++ b/tests/codegen/vec-reserve-extend.rs
@@ -1,4 +1,6 @@
 // compile-flags: -O
+// ignore-debug
+// (with debug assertions turned on, `assert_unchecked` generates a real assertion)
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/vec_pop_push_noop.rs b/tests/codegen/vec_pop_push_noop.rs
index 8bc7b68a816..d9293f2b75d 100644
--- a/tests/codegen/vec_pop_push_noop.rs
+++ b/tests/codegen/vec_pop_push_noop.rs
@@ -1,4 +1,6 @@
 // compile-flags: -O
+// ignore-debug
+// (with debug assertions turned on, `assert_unchecked` generates a real assertion)
 
 #![crate_type = "lib"]