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.
This commit is contained in:
The8472 2021-01-04 01:08:13 +01:00
parent 80184183ba
commit af2983a912
3 changed files with 23 additions and 0 deletions

View File

@ -286,6 +286,7 @@ where
#[inline]
unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item {
let idx = self.index + idx;
// SAFETY: the caller must uphold the contract for
// `Iterator::__iterator_get_unchecked`.
unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) }

View File

@ -2,6 +2,7 @@
use core::cell::Cell;
use core::convert::TryFrom;
use core::iter::TrustedRandomAccess;
use core::iter::*;
/// An iterator wrapper that panics whenever `next` or `next_back` is called
@ -601,6 +602,26 @@ fn test_zip_nth_back_side_effects_exhausted() {
assert_eq!(b, vec![200, 300, 400]);
}
#[test]
fn test_zip_trusted_random_access_composition() {
let a = [0, 1, 2, 3, 4];
let b = a;
let c = a;
let a = a.iter().copied();
let b = b.iter().copied();
let mut c = c.iter().copied();
c.next();
let mut z1 = a.zip(b);
assert_eq!(z1.next().unwrap(), (0, 0));
let mut z2 = z1.zip(c);
fn assert_trusted_random_access<T: TrustedRandomAccess>(_a: &T) {}
assert_trusted_random_access(&z2);
assert_eq!(z2.next().unwrap(), ((1, 1), 1));
}
#[test]
fn test_iterator_step_by() {
// Identity

View File

@ -73,6 +73,7 @@
#![feature(const_option)]
#![feature(integer_atomics)]
#![feature(slice_group_by)]
#![feature(trusted_random_access)]
#![deny(unsafe_op_in_unsafe_fn)]
extern crate test;