@@ -12,6 +12,7 @@ use crate::fmt;
1212use  crate :: hash:: { self ,  Hash } ; 
1313use  crate :: intrinsics:: transmute_unchecked; 
1414use  crate :: iter:: { UncheckedIterator ,  repeat_n} ; 
15+ use  crate :: marker:: Destruct ; 
1516use  crate :: mem:: { self ,  MaybeUninit } ; 
1617use  crate :: ops:: { 
1718    ChangeOutputType ,  ControlFlow ,  FromResidual ,  Index ,  IndexMut ,  NeverShortCircuit ,  Residual ,  Try , 
@@ -24,7 +25,6 @@ mod drain;
2425mod  equality; 
2526mod  iter; 
2627
27- pub ( crate )  use  drain:: drain_array_with; 
2828#[ stable( feature = "array_value_iter" ,  since = "1.51.0" ) ]  
2929pub  use  iter:: IntoIter ; 
3030
@@ -104,9 +104,10 @@ pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
104104/// ``` 
105105#[ inline]  
106106#[ stable( feature = "array_from_fn" ,  since = "1.63.0" ) ]  
107- pub  fn  from_fn < T ,  const  N :  usize ,  F > ( f :  F )  -> [ T ;  N ] 
107+ #[ rustc_const_unstable( feature = "const_array" ,  issue = "147606" ) ]  
108+ pub  const  fn  from_fn< T :  [ const ]  Destruct ,  const  N :  usize ,  F > ( f :  F )  -> [ T ;  N ] 
108109where 
109-     F :  FnMut ( usize )  -> T , 
110+     F :  [ const ]   FnMut ( usize )  -> T  +  [ const ]   Destruct , 
110111{ 
111112    try_from_fn ( NeverShortCircuit :: wrap_mut_1 ( f ) ) . 0 
112113} 
@@ -142,11 +143,13 @@ where
142143/// ``` 
143144#[ inline]  
144145#[ unstable( feature = "array_try_from_fn" ,  issue = "89379" ) ]  
145- pub  fn  try_from_fn < R ,  const  N :  usize ,  F > ( cb :  F )  -> ChangeOutputType < R ,  [ R :: Output ;  N ] > 
146+ #[ rustc_const_unstable( feature = "array_try_from_fn" ,  issue = "89379" ) ]  
147+ pub  const  fn  try_from_fn< R ,  const  N :  usize ,  F > ( cb :  F )  -> ChangeOutputType < R ,  [ R :: Output ;  N ] > 
146148where 
147-     F :  FnMut ( usize )  -> R , 
148-     R :  Try , 
149-     R :: Residual :  Residual < [ R :: Output ;  N ] > , 
149+     F :  [ const ]  FnMut ( usize )  -> R  + [ const ]  Destruct , 
150+     R :  [ const ]  Try < Residual :  Residual < [ R :: Output ;  N ] > > , 
151+     R :: Output :  [ const ]  Destruct , 
152+     <R :: Residual  as  Residual < [ R :: Output ;  N ] > >:: TryType :  [ const ]  Try , 
150153{ 
151154    let  mut  array  = [ const  {  MaybeUninit :: uninit ( )  } ;  N ] ; 
152155    match  try_from_fn_erased ( & mut  array,  cb)  { 
@@ -542,9 +545,11 @@ impl<T, const N: usize> [T; N] {
542545/// ``` 
543546#[ must_use]  
544547    #[ stable( feature = "array_map" ,  since = "1.55.0" ) ]  
545-     pub  fn  map < F ,  U > ( self ,  f :  F )  -> [ U ;  N ] 
548+     #[ rustc_const_unstable( feature = "const_array" ,  issue = "147606" ) ]  
549+     pub  const  fn  map< F ,  U > ( self ,  f :  F )  -> [ U ;  N ] 
546550    where 
547-         F :  FnMut ( T )  -> U , 
551+         F :  [ const ]  FnMut ( T )  -> U  + [ const ]  Destruct , 
552+         U :  [ const ]  Destruct , 
548553    { 
549554        self . try_map ( NeverShortCircuit :: wrap_mut_1 ( f ) ) . 0 
550555    } 
@@ -580,11 +585,19 @@ impl<T, const N: usize> [T; N] {
580585/// assert_eq!(c, Some(a)); 
581586/// ``` 
582587#[ unstable( feature = "array_try_map" ,  issue = "79711" ) ]  
583-     pub  fn  try_map < R > ( self ,  f :  impl  FnMut ( T )  -> R )  -> ChangeOutputType < R ,  [ R :: Output ;  N ] > 
588+     #[ rustc_const_unstable( feature = "array_try_map" ,  issue = "79711" ) ]  
589+     pub const  fn  try_map < R ,  F > ( self ,  mut  f :  F )  -> ChangeOutputType < R ,  [ R :: Output ;  N ] > 
584590    where 
585-         R :  Try < Residual :  Residual < [ R :: Output ;  N ] > > , 
591+         F :  [ const ]  FnMut ( T )  -> R  + [ const ]  Destruct , 
592+         R :  [ const ]  Try < Residual :  Residual < [ R :: Output ;  N ] > > , 
593+         R :: Output :  [ const ]  Destruct , 
594+         <R :: Residual  as  Residual < [ R :: Output ;  N ] > >:: TryType :  [ const ]  Try , 
586595    { 
587-         drain_array_with ( self ,  |iter| try_from_trusted_iterator ( iter. map ( f) ) ) 
596+         // SAFETY: try_from_fn calls `f` with 0..N. 
597+         let  mut  f = unsafe  {  drain:: Drain :: new ( self ,  & mut  f )  } ; 
598+         let out = try_from_fn ( & mut  f) ; 
599+         mem:: forget ( f) ;  // it doesnt like being remembered 
600+         out
588601    } 
589602
590603    /// Returns a slice containing the entire array. Equivalent to `&s[..]`. 
@@ -878,12 +891,15 @@ where
878891/// not optimizing away.  So if you give it a shot, make sure to watch what 
879892/// happens in the codegen tests. 
880893#[ inline]  
881- fn  try_from_fn_erased < T ,  R > ( 
894+ #[ rustc_const_unstable( feature = "array_try_from_fn" ,  issue = "89379" ) ]  
895+ const  fn  try_from_fn_erased< T ,  R ,  F > ( 
882896    buffer :  & mut  [ MaybeUninit < T > ] , 
883-     mut  generator :  impl   FnMut ( usize )  ->  R , 
897+     mut  generator :  F , 
884898)  -> ControlFlow < R :: Residual > 
885899where 
886-     R :  Try < Output  = T > , 
900+     T :  [ const ]  Destruct , 
901+     R :  [ const ]  Try < Output  = T > , 
902+     F :  [ const ]  FnMut ( usize )  -> R  + [ const ]  Destruct , 
887903{ 
888904    let  mut  guard  = Guard  {  array_mut :  buffer ,  initialized :  0  } ; 
889905
@@ -923,7 +939,8 @@ impl<T> Guard<'_, T> {
923939/// 
924940/// No more than N elements must be initialized. 
925941#[ inline]  
926-     pub ( crate )  unsafe  fn  push_unchecked ( & mut  self ,  item :  T )  { 
942+     #[ rustc_const_unstable( feature = "array_try_from_fn" ,  issue = "89379" ) ]  
943+     pub ( crate )  const  unsafe  fn  push_unchecked ( & mut  self ,  item :  T )  { 
927944        // SAFETY: If `initialized` was correct before and the caller does not 
928945        // invoke this method more than N times then writes will be in-bounds 
929946        // and slots will not be initialized more than once. 
@@ -934,11 +951,11 @@ impl<T> Guard<'_, T> {
934951    } 
935952} 
936953
937- impl < T >  Drop  for  Guard < ' _ ,  T >  { 
954+ #[ rustc_const_unstable( feature = "array_try_from_fn" ,  issue = "89379" ) ]  
955+ impl <T :  [ const ]  Destruct > const  Drop  for  Guard < ' _ ,  T >  { 
938956    #[ inline ] 
939957    fn drop ( & mut  self )  { 
940958        debug_assert ! ( self . initialized <= self . array_mut. len( ) ) ; 
941- 
942959        // SAFETY: this slice will contain only initialized objects. 
943960        unsafe  { 
944961            self . array_mut . get_unchecked_mut ( ..self . initialized ) . assume_init_drop ( ) ; 
0 commit comments