@@ -162,11 +162,19 @@ impl<T> AsRef<[T]> for Iter<'_, T> {
162
162
163
163
#[ unstable( feature = "ub_checks" , issue = "none" ) ]
164
164
impl < T > Invariant for Iter < ' _ , T > {
165
+ /// An iterator can be safely used if its pointer can be read for its current length.
166
+ ///
167
+ /// If the type is a ZST or the encoded length is `0`, the only safety requirement is that
168
+ /// its pointer is aligned (since zero-size access is always safe for aligned pointers),
169
+ /// and that `self.ptr` value is less or equal to `self.end_or_len`.
170
+ ///
171
+ /// For other cases, we need to ensure that it is safe to read the memory between
172
+ /// `self.ptr` and `self.end_or_len`.
165
173
fn is_safe ( & self ) -> bool {
166
174
let ty_size = crate :: mem:: size_of :: < T > ( ) ;
167
175
let distance = self . ptr . addr ( ) . get ( ) . abs_diff ( self . end_or_len as usize ) ;
168
176
if ty_size == 0 || distance == 0 {
169
- self . ptr . is_aligned ( )
177
+ self . ptr . is_aligned ( ) && self . ptr . addr ( ) . get ( ) <= self . end_or_len as usize
170
178
} else {
171
179
let slice_ptr: * const [ T ] =
172
180
crate :: ptr:: from_raw_parts ( self . ptr . as_ptr ( ) , distance / ty_size) ;
@@ -219,10 +227,14 @@ pub struct IterMut<'a, T: 'a> {
219
227
220
228
#[ unstable( feature = "ub_checks" , issue = "none" ) ]
221
229
impl < T > Invariant for IterMut < ' _ , T > {
230
+ /// This is similar to [Iter] with an extra write requirement.
231
+ ///
232
+ /// It must be safe to write in the memory interval between `self.ptr`
233
+ /// and `self.end_or_len`.
222
234
fn is_safe ( & self ) -> bool {
223
235
let size = crate :: mem:: size_of :: < T > ( ) ;
224
236
if size == 0 {
225
- self . ptr . is_aligned ( )
237
+ self . ptr . is_aligned ( ) && self . ptr . addr ( ) . get ( ) <= self . end_or_len as usize
226
238
} else {
227
239
let distance = self . ptr . addr ( ) . get ( ) . abs_diff ( self . end_or_len as usize ) ;
228
240
let slice_ptr: * mut [ T ] =
@@ -3632,6 +3644,7 @@ mod verify {
3632
3644
} ;
3633
3645
}
3634
3646
3647
+ // FIXME: Add harnesses for ZST with alignment > 1.
3635
3648
check_iter_with_ty ! ( verify_unit, ( ) , isize :: MAX as usize ) ;
3636
3649
check_iter_with_ty ! ( verify_u8, u8 , u32 :: MAX as usize ) ;
3637
3650
check_iter_with_ty ! ( verify_char, char , 50 ) ;
0 commit comments