diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 2272f8648e03d..be1bd5fdd2bb9 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1589,6 +1589,7 @@ macro_rules! int_impl { let mut base = self; let mut acc: Self = 1; + #[safety::loop_invariant(true)] loop { if (exp & 1) == 1 { acc = try_opt!(acc.checked_mul(base)); @@ -2299,6 +2300,7 @@ macro_rules! int_impl { let mut acc: Self = 1; if intrinsics::is_val_statically_known(exp) { + #[safety::loop_invariant(exp>=1)] while exp > 1 { if (exp & 1) == 1 { acc = acc.wrapping_mul(base); @@ -2316,6 +2318,7 @@ macro_rules! int_impl { // at compile time. We can't use the same code for the constant // exponent case because LLVM is currently unable to unroll // this loop. + #[safety::loop_invariant(true)] loop { if (exp & 1) == 1 { acc = acc.wrapping_mul(base); diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f7c5d65d8b7bc..f45297afcae0a 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1780,6 +1780,7 @@ macro_rules! uint_impl { let mut base = self; let mut acc: Self = 1; + #[safety::loop_invariant(true)] loop { if (exp & 1) == 1 { acc = try_opt!(acc.checked_mul(base)); @@ -2349,6 +2350,7 @@ macro_rules! uint_impl { let mut acc: Self = 1; if intrinsics::is_val_statically_known(exp) { + #[safety::loop_invariant(exp>=1)] while exp > 1 { if (exp & 1) == 1 { acc = acc.wrapping_mul(base); @@ -2366,6 +2368,7 @@ macro_rules! uint_impl { // at compile time. We can't use the same code for the constant // exponent case because LLVM is currently unable to unroll // this loop. + #[safety::loop_invariant(true)] loop { if (exp & 1) == 1 { acc = acc.wrapping_mul(base); @@ -3044,6 +3047,7 @@ macro_rules! uint_impl { // Scratch space for storing results of overflowing_mul. let mut r; + #[safety::loop_invariant(true)] loop { if (exp & 1) == 1 { r = acc.overflowing_mul(base); diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index b14348ba986ab..79481e244fb40 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -478,6 +478,7 @@ const fn is_ascii(bytes: &[u8]) -> bool { let mut i = 0; + #[safety::loop_invariant(i <= bytes.len())] while i + CHUNK_SIZE <= bytes.len() { let chunk_end = i + CHUNK_SIZE; @@ -486,6 +487,7 @@ const fn is_ascii(bytes: &[u8]) -> bool { // ASCII bytes are less than 128 (0x80), so their most significant // bit is unset. let mut count = 0; + #[safety::loop_invariant(i <= chunk_end && chunk_end - i <= CHUNK_SIZE && i - (chunk_end - CHUNK_SIZE) >= count as usize)] while i < chunk_end { count += bytes[i].is_ascii() as u8; i += 1; @@ -499,6 +501,7 @@ const fn is_ascii(bytes: &[u8]) -> bool { // Process the remaining `bytes.len() % N` bytes. let mut is_ascii = true; + #[safety::loop_invariant(i <= bytes.len())] while i < bytes.len() { is_ascii &= bytes[i].is_ascii(); i += 1;