Skip to content

Commit af2983a

Browse files
committed
TrustedRandomAaccess spec composes incorrectly for nested iter::Zips
After partially consuming a Zip adapter and then wrapping it into another Zip where the adapters use their TrustedRandomAccess specializations leads to the outer adapter returning elements which should have already been consumed.
1 parent 8018418 commit af2983a

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ where
286286

287287
#[inline]
288288
unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item {
289+
let idx = self.index + idx;
289290
// SAFETY: the caller must uphold the contract for
290291
// `Iterator::__iterator_get_unchecked`.
291292
unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) }

library/core/tests/iter.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use core::cell::Cell;
44
use core::convert::TryFrom;
5+
use core::iter::TrustedRandomAccess;
56
use core::iter::*;
67

78
/// An iterator wrapper that panics whenever `next` or `next_back` is called
@@ -601,6 +602,26 @@ fn test_zip_nth_back_side_effects_exhausted() {
601602
assert_eq!(b, vec![200, 300, 400]);
602603
}
603604

605+
#[test]
606+
fn test_zip_trusted_random_access_composition() {
607+
let a = [0, 1, 2, 3, 4];
608+
let b = a;
609+
let c = a;
610+
611+
let a = a.iter().copied();
612+
let b = b.iter().copied();
613+
let mut c = c.iter().copied();
614+
c.next();
615+
616+
let mut z1 = a.zip(b);
617+
assert_eq!(z1.next().unwrap(), (0, 0));
618+
619+
let mut z2 = z1.zip(c);
620+
fn assert_trusted_random_access<T: TrustedRandomAccess>(_a: &T) {}
621+
assert_trusted_random_access(&z2);
622+
assert_eq!(z2.next().unwrap(), ((1, 1), 1));
623+
}
624+
604625
#[test]
605626
fn test_iterator_step_by() {
606627
// Identity

library/core/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#![feature(const_option)]
7474
#![feature(integer_atomics)]
7575
#![feature(slice_group_by)]
76+
#![feature(trusted_random_access)]
7677
#![deny(unsafe_op_in_unsafe_fn)]
7778

7879
extern crate test;

0 commit comments

Comments
 (0)