@@ -11,6 +11,7 @@ use crate::error::Error;
1111use crate :: fmt;
1212use crate :: hash:: { self , Hash } ;
1313use crate :: iter:: UncheckedIterator ;
14+ use crate :: marker:: Destruct ;
1415use crate :: mem:: { self , MaybeUninit } ;
1516use crate :: ops:: {
1617 ChangeOutputType , ControlFlow , FromResidual , Index , IndexMut , NeverShortCircuit , Residual , Try ,
@@ -55,9 +56,11 @@ pub use iter::IntoIter;
5556/// ```
5657#[ inline]
5758#[ stable( feature = "array_from_fn" , since = "1.63.0" ) ]
58- pub fn from_fn < T , const N : usize , F > ( cb : F ) -> [ T ; N ]
59+ #[ rustc_const_unstable( feature = "const_array_from_fn" , issue = "none" ) ]
60+ pub const fn from_fn < T , const N : usize , F > ( cb : F ) -> [ T ; N ]
5961where
60- F : FnMut ( usize ) -> T ,
62+ F : ~const FnMut ( usize ) -> T + ~const Destruct ,
63+ T : ~const Destruct ,
6164{
6265 try_from_fn ( NeverShortCircuit :: wrap_mut_1 ( cb) ) . 0
6366}
@@ -93,11 +96,12 @@ where
9396/// ```
9497#[ inline]
9598#[ unstable( feature = "array_try_from_fn" , issue = "89379" ) ]
96- pub fn try_from_fn < R , const N : usize , F > ( cb : F ) -> ChangeOutputType < R , [ R :: Output ; N ] >
99+ pub const fn try_from_fn < R , const N : usize , F > ( cb : F ) -> ChangeOutputType < R , [ R :: Output ; N ] >
97100where
98- F : FnMut ( usize ) -> R ,
99- R : Try ,
100- R :: Residual : Residual < [ R :: Output ; N ] > ,
101+ F : ~const FnMut ( usize ) -> R + ~const Destruct ,
102+ R : ~const Try ,
103+ R :: Residual : ~const Residual < [ R :: Output ; N ] > ,
104+ R :: Output : ~const Destruct ,
101105{
102106 let mut array = MaybeUninit :: uninit_array :: < N > ( ) ;
103107 match try_from_fn_erased ( & mut array, cb) {
@@ -835,12 +839,14 @@ where
835839/// not optimizing away. So if you give it a shot, make sure to watch what
836840/// happens in the codegen tests.
837841#[ inline]
838- fn try_from_fn_erased < T , R > (
842+ #[ rustc_const_unstable( feature = "const_array_from_fn" , issue = "none" ) ]
843+ const fn try_from_fn_erased < T , R > (
839844 buffer : & mut [ MaybeUninit < T > ] ,
840- mut generator : impl FnMut ( usize ) -> R ,
845+ mut generator : impl ~ const FnMut ( usize ) -> R + ~ const Destruct ,
841846) -> ControlFlow < R :: Residual >
842847where
843- R : Try < Output = T > ,
848+ R : ~const Try < Output = T > ,
849+ R :: Output : ~const Destruct ,
844850{
845851 let mut guard = Guard { array_mut : buffer, initialized : 0 } ;
846852
@@ -866,7 +872,7 @@ where
866872///
867873/// To minimize indirection fields are still pub but callers should at least use
868874/// `push_unchecked` to signal that something unsafe is going on.
869- struct Guard < ' a , T > {
875+ struct Guard < ' a , T : ~ const Destruct > {
870876 /// The array to be initialized.
871877 pub array_mut : & ' a mut [ MaybeUninit < T > ] ,
872878 /// The number of items that have been initialized so far.
@@ -880,7 +886,7 @@ impl<T> Guard<'_, T> {
880886 ///
881887 /// No more than N elements must be initialized.
882888 #[ inline]
883- pub unsafe fn push_unchecked ( & mut self , item : T ) {
889+ pub const unsafe fn push_unchecked ( & mut self , item : T ) {
884890 // SAFETY: If `initialized` was correct before and the caller does not
885891 // invoke this method more than N times then writes will be in-bounds
886892 // and slots will not be initialized more than once.
@@ -891,7 +897,7 @@ impl<T> Guard<'_, T> {
891897 }
892898}
893899
894- impl < T > Drop for Guard < ' _ , T > {
900+ impl < T : ~ const Destruct > const Drop for Guard < ' _ , T > {
895901 fn drop ( & mut self ) {
896902 debug_assert ! ( self . initialized <= self . array_mut. len( ) ) ;
897903
0 commit comments