11use  core:: fmt; 
22use  core:: iter:: { FusedIterator ,  TrustedLen ,  TrustedRandomAccess ,  TrustedRandomAccessNoCoerce } ; 
3+ use  core:: mem:: MaybeUninit ; 
34use  core:: ops:: Try ; 
45
56use  super :: { count,  wrap_index,  RingSlices } ; 
@@ -12,7 +13,7 @@ use super::{count, wrap_index, RingSlices};
1213/// [`iter`]: super::VecDeque::iter 
1314#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
1415pub  struct  Iter < ' a ,  T :  ' a >  { 
15-     pub ( crate )  ring :  & ' a  [ T ] , 
16+     pub ( crate )  ring :  & ' a  [ MaybeUninit < T > ] , 
1617    pub ( crate )  tail :  usize , 
1718    pub ( crate )  head :  usize , 
1819} 
@@ -44,7 +45,10 @@ impl<'a, T> Iterator for Iter<'a, T> {
4445        } 
4546        let  tail = self . tail ; 
4647        self . tail  = wrap_index ( self . tail . wrapping_add ( 1 ) ,  self . ring . len ( ) ) ; 
47-         unsafe  {  Some ( self . ring . get_unchecked ( tail) )  } 
48+         // Safety: 
49+         // - `self.tail` in a ring buffer is always a valid index. 
50+         // - `self.head` and `self.tail` equality is checked above. 
51+         unsafe  {  Some ( self . ring . get_unchecked ( tail) . assume_init_ref ( ) )  } 
4852    } 
4953
5054    #[ inline]  
@@ -58,8 +62,13 @@ impl<'a, T> Iterator for Iter<'a, T> {
5862        F :  FnMut ( Acc ,  Self :: Item )  -> Acc , 
5963    { 
6064        let  ( front,  back)  = RingSlices :: ring_slices ( self . ring ,  self . head ,  self . tail ) ; 
61-         accum = front. iter ( ) . fold ( accum,  & mut  f) ; 
62-         back. iter ( ) . fold ( accum,  & mut  f) 
65+         // Safety: 
66+         // - `self.head` and `self.tail` in a ring buffer are always valid indices. 
67+         // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized. 
68+         unsafe  { 
69+             accum = MaybeUninit :: slice_assume_init_ref ( front) . iter ( ) . fold ( accum,  & mut  f) ; 
70+             MaybeUninit :: slice_assume_init_ref ( back) . iter ( ) . fold ( accum,  & mut  f) 
71+         } 
6372    } 
6473
6574    fn  try_fold < B ,  F ,  R > ( & mut  self ,  init :  B ,  mut  f :  F )  -> R 
@@ -70,17 +79,19 @@ impl<'a, T> Iterator for Iter<'a, T> {
7079    { 
7180        let  ( mut  iter,  final_res) ; 
7281        if  self . tail  <= self . head  { 
73-             // single slice self.ring[self.tail..self.head] 
74-             iter = self . ring [ self . tail ..self . head ] . iter ( ) ; 
82+             // Safety: single slice self.ring[self.tail..self.head] is initialized. 
83+             iter = unsafe  {  MaybeUninit :: slice_assume_init_ref ( & self . ring [ self . tail ..self . head ] )  } 
84+                 . iter ( ) ; 
7585            final_res = iter. try_fold ( init,  & mut  f) ; 
7686        }  else  { 
77-             // two slices: self.ring[self.tail..], self.ring[..self.head] 
87+             // Safety:  two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.  
7888            let  ( front,  back)  = self . ring . split_at ( self . tail ) ; 
79-             let  mut  back_iter = back. iter ( ) ; 
89+ 
90+             let  mut  back_iter = unsafe  {  MaybeUninit :: slice_assume_init_ref ( back) . iter ( )  } ; 
8091            let  res = back_iter. try_fold ( init,  & mut  f) ; 
8192            let  len = self . ring . len ( ) ; 
8293            self . tail  = ( self . ring . len ( )  - back_iter. len ( ) )  &  ( len - 1 ) ; 
83-             iter = front[ ..self . head ] . iter ( ) ; 
94+             iter = unsafe   {   MaybeUninit :: slice_assume_init_ref ( & front[ ..self . head ] ) . iter ( )   } ; 
8495            final_res = iter. try_fold ( res?,  & mut  f) ; 
8596        } 
8697        self . tail  = self . head  - iter. len ( ) ; 
@@ -109,7 +120,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
109120        // that is in bounds. 
110121        unsafe  { 
111122            let  idx = wrap_index ( self . tail . wrapping_add ( idx) ,  self . ring . len ( ) ) ; 
112-             self . ring . get_unchecked ( idx) 
123+             self . ring . get_unchecked ( idx) . assume_init_ref ( ) 
113124        } 
114125    } 
115126} 
@@ -122,16 +133,24 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
122133            return  None ; 
123134        } 
124135        self . head  = wrap_index ( self . head . wrapping_sub ( 1 ) ,  self . ring . len ( ) ) ; 
125-         unsafe  {  Some ( self . ring . get_unchecked ( self . head ) )  } 
136+         // Safety: 
137+         // - `self.head` in a ring buffer is always a valid index. 
138+         // - `self.head` and `self.tail` equality is checked above. 
139+         unsafe  {  Some ( self . ring . get_unchecked ( self . head ) . assume_init_ref ( ) )  } 
126140    } 
127141
128142    fn  rfold < Acc ,  F > ( self ,  mut  accum :  Acc ,  mut  f :  F )  -> Acc 
129143    where 
130144        F :  FnMut ( Acc ,  Self :: Item )  -> Acc , 
131145    { 
132146        let  ( front,  back)  = RingSlices :: ring_slices ( self . ring ,  self . head ,  self . tail ) ; 
133-         accum = back. iter ( ) . rfold ( accum,  & mut  f) ; 
134-         front. iter ( ) . rfold ( accum,  & mut  f) 
147+         // Safety: 
148+         // - `self.head` and `self.tail` in a ring buffer are always valid indices. 
149+         // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized. 
150+         unsafe  { 
151+             accum = MaybeUninit :: slice_assume_init_ref ( back) . iter ( ) . rfold ( accum,  & mut  f) ; 
152+             MaybeUninit :: slice_assume_init_ref ( front) . iter ( ) . rfold ( accum,  & mut  f) 
153+         } 
135154    } 
136155
137156    fn  try_rfold < B ,  F ,  R > ( & mut  self ,  init :  B ,  mut  f :  F )  -> R 
@@ -142,16 +161,20 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
142161    { 
143162        let  ( mut  iter,  final_res) ; 
144163        if  self . tail  <= self . head  { 
145-             // single slice self.ring[self.tail..self.head] 
146-             iter = self . ring [ self . tail ..self . head ] . iter ( ) ; 
164+             // Safety: single slice self.ring[self.tail..self.head] is initialized. 
165+             iter = unsafe  { 
166+                 MaybeUninit :: slice_assume_init_ref ( & self . ring [ self . tail ..self . head ] ) . iter ( ) 
167+             } ; 
147168            final_res = iter. try_rfold ( init,  & mut  f) ; 
148169        }  else  { 
149-             // two slices: self.ring[self.tail..], self.ring[..self.head] 
170+             // Safety:  two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.  
150171            let  ( front,  back)  = self . ring . split_at ( self . tail ) ; 
151-             let  mut  front_iter = front[ ..self . head ] . iter ( ) ; 
172+ 
173+             let  mut  front_iter =
174+                 unsafe  {  MaybeUninit :: slice_assume_init_ref ( & front[ ..self . head ] ) . iter ( )  } ; 
152175            let  res = front_iter. try_rfold ( init,  & mut  f) ; 
153176            self . head  = front_iter. len ( ) ; 
154-             iter = back. iter ( ) ; 
177+             iter = unsafe   {   MaybeUninit :: slice_assume_init_ref ( back) . iter ( )   } ; 
155178            final_res = iter. try_rfold ( res?,  & mut  f) ; 
156179        } 
157180        self . head  = self . tail  + iter. len ( ) ; 
0 commit comments