@@ -11,6 +11,7 @@ use crate::error::Error;
11
11
use crate :: fmt;
12
12
use crate :: hash:: { self , Hash } ;
13
13
use crate :: iter:: UncheckedIterator ;
14
+ use crate :: marker:: Destruct ;
14
15
use crate :: mem:: { self , MaybeUninit } ;
15
16
use crate :: ops:: {
16
17
ChangeOutputType , ControlFlow , FromResidual , Index , IndexMut , NeverShortCircuit , Residual , Try ,
@@ -55,9 +56,11 @@ pub use iter::IntoIter;
55
56
/// ```
56
57
#[ inline]
57
58
#[ 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 ]
59
61
where
60
- F : FnMut ( usize ) -> T ,
62
+ F : ~const FnMut ( usize ) -> T + ~const Destruct ,
63
+ T : ~const Destruct ,
61
64
{
62
65
try_from_fn ( NeverShortCircuit :: wrap_mut_1 ( cb) ) . 0
63
66
}
@@ -93,11 +96,12 @@ where
93
96
/// ```
94
97
#[ inline]
95
98
#[ 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 ] >
97
100
where
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 ,
101
105
{
102
106
let mut array = MaybeUninit :: uninit_array :: < N > ( ) ;
103
107
match try_from_fn_erased ( & mut array, cb) {
@@ -835,12 +839,14 @@ where
835
839
/// not optimizing away. So if you give it a shot, make sure to watch what
836
840
/// happens in the codegen tests.
837
841
#[ 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 > (
839
844
buffer : & mut [ MaybeUninit < T > ] ,
840
- mut generator : impl FnMut ( usize ) -> R ,
845
+ mut generator : impl ~ const FnMut ( usize ) -> R + ~ const Destruct ,
841
846
) -> ControlFlow < R :: Residual >
842
847
where
843
- R : Try < Output = T > ,
848
+ R : ~const Try < Output = T > ,
849
+ R :: Output : ~const Destruct ,
844
850
{
845
851
let mut guard = Guard { array_mut : buffer, initialized : 0 } ;
846
852
@@ -866,7 +872,7 @@ where
866
872
///
867
873
/// To minimize indirection fields are still pub but callers should at least use
868
874
/// `push_unchecked` to signal that something unsafe is going on.
869
- struct Guard < ' a , T > {
875
+ struct Guard < ' a , T : ~ const Destruct > {
870
876
/// The array to be initialized.
871
877
pub array_mut : & ' a mut [ MaybeUninit < T > ] ,
872
878
/// The number of items that have been initialized so far.
@@ -880,7 +886,7 @@ impl<T> Guard<'_, T> {
880
886
///
881
887
/// No more than N elements must be initialized.
882
888
#[ inline]
883
- pub unsafe fn push_unchecked ( & mut self , item : T ) {
889
+ pub const unsafe fn push_unchecked ( & mut self , item : T ) {
884
890
// SAFETY: If `initialized` was correct before and the caller does not
885
891
// invoke this method more than N times then writes will be in-bounds
886
892
// and slots will not be initialized more than once.
@@ -891,7 +897,7 @@ impl<T> Guard<'_, T> {
891
897
}
892
898
}
893
899
894
- impl < T > Drop for Guard < ' _ , T > {
900
+ impl < T : ~ const Destruct > const Drop for Guard < ' _ , T > {
895
901
fn drop ( & mut self ) {
896
902
debug_assert ! ( self . initialized <= self . array_mut. len( ) ) ;
897
903
0 commit comments