Skip to content

Commit bba1224

Browse files
vonakaFedor Ryabinintautschnigfeliperodri
authored
LLM-generated contracts for __iterator_get_unchecked (#435)
Preconditions generated by Claude for files containing `__iterator_get_unchecked`. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses. --------- Co-authored-by: Fedor Ryabinin <rfedor@amazon.com> Co-authored-by: Michael Tautschnig <tautschn@amazon.com> Co-authored-by: Felipe R. Monteiro <rms.felipe@gmail.com>
1 parent e4dcb19 commit bba1224

File tree

17 files changed

+102
-0
lines changed

17 files changed

+102
-0
lines changed

library/alloc/src/collections/vec_deque/iter.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
2+
#[cfg(kani)]
3+
use core::kani;
24
use core::num::NonZero;
35
use core::ops::Try;
46
use core::{fmt, mem, slice};
57

8+
use safety::requires;
9+
610
/// An iterator over the elements of a `VecDeque`.
711
///
812
/// This `struct` is created by the [`iter`] method on [`super::VecDeque`]. See its
@@ -144,6 +148,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
144148
}
145149

146150
#[inline]
151+
#[requires(idx < self.len())]
152+
#[cfg_attr(kani, kani::modifies(self))]
147153
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
148154
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
149155
// that is in bounds.

library/alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
2+
#[cfg(kani)]
3+
use core::kani;
24
use core::num::NonZero;
35
use core::ops::Try;
46
use core::{fmt, mem, slice};
57

8+
use safety::requires;
9+
610
/// A mutable iterator over the elements of a `VecDeque`.
711
///
812
/// This `struct` is created by the [`iter_mut`] method on [`super::VecDeque`]. See its
@@ -208,6 +212,8 @@ impl<'a, T> Iterator for IterMut<'a, T> {
208212
}
209213

210214
#[inline]
215+
#[requires(idx < self.len())]
216+
#[cfg_attr(kani, kani::modifies(self))]
211217
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
212218
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
213219
// that is in bounds.

library/alloc/src/vec/into_iter.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use core::iter::{
22
FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen,
33
TrustedRandomAccessNoCoerce,
44
};
5+
#[cfg(kani)]
6+
use core::kani;
57
use core::marker::PhantomData;
68
use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
79
use core::num::NonZero;
@@ -11,6 +13,8 @@ use core::ptr::{self, NonNull};
1113
use core::slice::{self};
1214
use core::{array, fmt};
1315

16+
use safety::requires;
17+
1418
#[cfg(not(no_global_oom_handling))]
1519
use super::AsVecIntoIter;
1620
use crate::alloc::{Allocator, Global};
@@ -354,6 +358,8 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
354358
R::from_output(accum)
355359
}
356360

361+
#[requires(i < self.len())]
362+
#[cfg_attr(kani, kani::modifies(self))]
357363
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
358364
where
359365
Self: TrustedRandomAccessNoCoerce,

library/core/src/array/iter.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
//! Defines the `IntoIter` owned iterator for arrays.
22
3+
use safety::requires;
4+
35
use crate::intrinsics::transmute_unchecked;
46
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccessNoCoerce};
7+
#[cfg(kani)]
8+
use crate::kani;
59
use crate::mem::MaybeUninit;
610
use crate::num::NonZero;
711
use crate::ops::{IndexRange, Range, Try};
@@ -138,6 +142,8 @@ impl<T, const N: usize> IntoIter<T, N> {
138142
/// ```
139143
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]
140144
#[inline]
145+
#[requires(initialized.start <= initialized.end)]
146+
#[requires(initialized.end <= N)]
141147
pub const unsafe fn new_unchecked(
142148
buffer: [MaybeUninit<T>; N],
143149
initialized: Range<usize>,
@@ -279,6 +285,8 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
279285
}
280286

281287
#[inline]
288+
#[requires(idx < self.len())]
289+
#[cfg_attr(kani, kani::modifies(self))]
282290
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
283291
// SAFETY: The caller must provide an idx that is in bound of the remainder.
284292
let elem_ref = unsafe { self.as_mut_slice().get_unchecked_mut(idx) };

library/core/src/char/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ mod convert;
2424
mod decode;
2525
mod methods;
2626

27+
use safety::requires;
28+
2729
// stable re-exports
2830
#[rustfmt::skip]
2931
#[stable(feature = "try_from", since = "1.34.0")]
@@ -47,6 +49,8 @@ use crate::error::Error;
4749
use crate::escape::{AlwaysEscaped, EscapeIterInner, MaybeEscaped};
4850
use crate::fmt::{self, Write};
4951
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
52+
#[cfg(kani)]
53+
use crate::kani;
5054
use crate::num::NonZero;
5155

5256
// UTF-8 ranges and tags for encoding characters
@@ -138,6 +142,7 @@ pub const fn from_u32(i: u32) -> Option<char> {
138142
#[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")]
139143
#[must_use]
140144
#[inline]
145+
#[requires(i <= 0x10FFFF && (i < 0xD800 || i > 0xDFFF))]
141146
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
142147
// SAFETY: the safety contract must be upheld by the caller.
143148
unsafe { self::convert::from_u32_unchecked(i) }
@@ -399,6 +404,7 @@ macro_rules! casemappingiter_impls {
399404
self.0.advance_by(n)
400405
}
401406

407+
#[requires(idx < self.0.len())]
402408
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
403409
// SAFETY: just forwarding requirements to caller
404410
unsafe { self.0.__iterator_get_unchecked(idx) }
@@ -533,6 +539,8 @@ impl Iterator for CaseMappingIter {
533539
self.0.advance_by(n)
534540
}
535541

542+
#[requires(idx < self.len())]
543+
#[cfg_attr(kani, kani::modifies(self))]
536544
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
537545
// SAFETY: just forwarding requirements to caller
538546
unsafe { self.0.__iterator_get_unchecked(idx) }

library/core/src/iter/adapters/cloned.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use core::num::NonZero;
22

3+
use safety::requires;
4+
35
use crate::iter::adapters::zip::try_get_unchecked;
46
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
57
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
8+
#[cfg(kani)]
9+
use crate::kani;
610
use crate::ops::Try;
711

812
/// An iterator that clones the elements of an underlying iterator.
@@ -61,6 +65,7 @@ where
6165
self.it.map(T::clone).fold(init, f)
6266
}
6367

68+
#[requires(idx < self.it.size_hint().0)]
6469
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
6570
where
6671
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/copied.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
use safety::requires;
2+
13
use crate::iter::adapters::zip::try_get_unchecked;
24
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
35
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
6+
#[cfg(kani)]
7+
use crate::kani;
48
use crate::mem::{MaybeUninit, SizedTypeProperties};
59
use crate::num::NonZero;
610
use crate::ops::Try;
@@ -92,6 +96,7 @@ where
9296
self.it.advance_by(n)
9397
}
9498

99+
#[requires(idx < self.it.size_hint().0)]
95100
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
96101
where
97102
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/enumerate.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
use safety::requires;
2+
13
use crate::iter::adapters::zip::try_get_unchecked;
24
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
35
use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen};
6+
#[cfg(kani)]
7+
use crate::kani;
48
use crate::num::NonZero;
59
use crate::ops::Try;
610

@@ -160,6 +164,8 @@ where
160164

161165
#[rustc_inherit_overflow_checks]
162166
#[inline]
167+
#[requires(idx < self.iter.size_hint().0)]
168+
#[cfg_attr(kani, kani::modifies(self))]
163169
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
164170
where
165171
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/fuse.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
use safety::requires;
2+
13
use crate::intrinsics;
24
use crate::iter::adapters::SourceIter;
35
use crate::iter::adapters::zip::try_get_unchecked;
46
use crate::iter::{
57
FusedIterator, TrustedFused, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
68
};
9+
#[cfg(kani)]
10+
use crate::kani;
711
use crate::ops::Try;
812

913
/// An iterator that yields `None` forever after the underlying iterator
@@ -109,6 +113,8 @@ where
109113
}
110114

111115
#[inline]
116+
#[requires(self.iter.is_some() && idx < self.iter.as_ref().unwrap().size_hint().0)]
117+
#[cfg_attr(kani, kani::modifies(self))]
112118
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
113119
where
114120
Self: TrustedRandomAccessNoCoerce,

library/core/src/iter/adapters/map.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
use safety::requires;
2+
13
use crate::fmt;
24
use crate::iter::adapters::zip::try_get_unchecked;
35
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
46
use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen, UncheckedIterator};
7+
#[cfg(kani)]
8+
use crate::kani;
59
use crate::num::NonZero;
610
use crate::ops::Try;
711

@@ -129,6 +133,7 @@ where
129133
}
130134

131135
#[inline]
136+
#[requires(idx < self.iter.size_hint().0)]
132137
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
133138
where
134139
Self: TrustedRandomAccessNoCoerce,

0 commit comments

Comments
 (0)