1+ use  crate :: fmt; 
12use  crate :: iter:: { FusedIterator ,  TrustedLen ,  UncheckedIterator } ; 
2- use  crate :: mem:: ManuallyDrop ; 
3+ use  crate :: mem:: { self ,   MaybeUninit } ; 
34use  crate :: num:: NonZero ; 
45
56/// Creates a new iterator that repeats a single element a given number of times. 
@@ -58,14 +59,12 @@ use crate::num::NonZero;
5859#[ inline]  
5960#[ stable( feature = "iter_repeat_n" ,  since = "1.82.0" ) ]  
6061pub  fn  repeat_n < T :  Clone > ( element :  T ,  count :  usize )  -> RepeatN < T >  { 
61-     let  mut  element = ManuallyDrop :: new ( element) ; 
62- 
63-     if  count == 0  { 
64-         // SAFETY: we definitely haven't dropped it yet, since we only just got 
65-         // passed it in, and because the count is zero the instance we're about 
66-         // to create won't drop it, so to avoid leaking we need to now. 
67-         unsafe  {  ManuallyDrop :: drop ( & mut  element)  } ; 
68-     } 
62+     let  element = if  count == 0  { 
63+         // `element` gets dropped eagerly. 
64+         MaybeUninit :: uninit ( ) 
65+     }  else  { 
66+         MaybeUninit :: new ( element) 
67+     } ; 
6968
7069    RepeatN  {  element,  count } 
7170} 
@@ -74,31 +73,60 @@ pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
7473/// 
7574/// This `struct` is created by the [`repeat_n()`] function. 
7675/// See its documentation for more. 
77- #[ derive( Clone ,  Debug ) ]  
7876#[ stable( feature = "iter_repeat_n" ,  since = "1.82.0" ) ]  
7977pub  struct  RepeatN < A >  { 
8078    count :  usize , 
81-     // Invariant: has been dropped  iff count == 0. 
82-     element :  ManuallyDrop < A > , 
79+     // Invariant: uninit  iff count == 0. 
80+     element :  MaybeUninit < A > , 
8381} 
8482
8583impl < A >  RepeatN < A >  { 
84+     /// Returns the element if it hasn't been dropped already. 
85+ fn  element_ref ( & self )  -> Option < & A >  { 
86+         if  self . count  > 0  { 
87+             // SAFETY: The count is non-zero, so it must be initialized. 
88+             Some ( unsafe  {  self . element . assume_init_ref ( )  } ) 
89+         }  else  { 
90+             None 
91+         } 
92+     } 
8693    /// If we haven't already dropped the element, return it in an option. 
8794/// 
8895/// Clears the count so it won't be dropped again later. 
8996#[ inline]  
9097    fn  take_element ( & mut  self )  -> Option < A >  { 
9198        if  self . count  > 0  { 
9299            self . count  = 0 ; 
100+             let  element = mem:: replace ( & mut  self . element ,  MaybeUninit :: uninit ( ) ) ; 
93101            // SAFETY: We just set count to zero so it won't be dropped again, 
94102            // and it used to be non-zero so it hasn't already been dropped. 
95-             unsafe  {  Some ( ManuallyDrop :: take ( & mut   self . element ) )  } 
103+             unsafe  {  Some ( element. assume_init ( ) )  } 
96104        }  else  { 
97105            None 
98106        } 
99107    } 
100108} 
101109
110+ #[ stable( feature = "iter_repeat_n" ,  since = "1.82.0" ) ]  
111+ impl < A :  Clone >  Clone  for  RepeatN < A >  { 
112+     fn  clone ( & self )  -> RepeatN < A >  { 
113+         RepeatN  { 
114+             count :  self . count , 
115+             element :  self . element_ref ( ) . cloned ( ) . map_or_else ( MaybeUninit :: uninit,  MaybeUninit :: new) , 
116+         } 
117+     } 
118+ } 
119+ 
120+ #[ stable( feature = "iter_repeat_n" ,  since = "1.82.0" ) ]  
121+ impl < A :  fmt:: Debug >  fmt:: Debug  for  RepeatN < A >  { 
122+     fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
123+         f. debug_struct ( "RepeatN" ) 
124+             . field ( "count" ,  & self . count ) 
125+             . field ( "element" ,  & self . element_ref ( ) ) 
126+             . finish ( ) 
127+     } 
128+ } 
129+ 
102130#[ stable( feature = "iter_repeat_n" ,  since = "1.82.0" ) ]  
103131impl < A >  Drop  for  RepeatN < A >  { 
104132    fn  drop ( & mut  self )  { 
@@ -194,9 +222,11 @@ impl<A: Clone> UncheckedIterator for RepeatN<A> {
194222            // SAFETY: the check above ensured that the count used to be non-zero, 
195223            // so element hasn't been dropped yet, and we just lowered the count to 
196224            // zero so it won't be dropped later, and thus it's okay to take it here. 
197-             unsafe  {  ManuallyDrop :: take ( & mut  self . element )  } 
225+             unsafe  {  mem :: replace ( & mut  self . element ,   MaybeUninit :: uninit ( ) ) . assume_init ( )  } 
198226        }  else  { 
199-             A :: clone ( & self . element ) 
227+             // SAFETY: the count is non-zero, so it must have not been dropped yet. 
228+             let  element = unsafe  {  self . element . assume_init_ref ( )  } ; 
229+             A :: clone ( element) 
200230        } 
201231    } 
202232} 
0 commit comments