@@ -3183,6 +3183,57 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
31833183 <T as SpecFromElem >:: from_elem ( elem, n, alloc)
31843184}
31853185
3186+ /// # Safety
3187+ ///
3188+ /// `elem` must be the result of some const expression.
3189+ #[ doc( hidden) ]
3190+ #[ cfg( not( no_global_oom_handling) ) ]
3191+ #[ unstable( feature = "vec_of_const_expr" , issue = "none" ) ]
3192+ #[ track_caller]
3193+ pub unsafe fn from_const_elem < T > ( elem : T , n : usize ) -> Vec < T > {
3194+ // SAFETY: Caller has guaranteed `elem` being the result of some const expression.
3195+ unsafe { from_const_elem_in ( elem, n, Global ) }
3196+ }
3197+
3198+ /// # Safety
3199+ ///
3200+ /// `elem` must be the result of some const expression.
3201+ #[ doc( hidden) ]
3202+ #[ cfg( not( no_global_oom_handling) ) ]
3203+ #[ unstable( feature = "vec_of_const_expr" , issue = "none" ) ]
3204+ #[ track_caller]
3205+ unsafe fn from_const_elem_in < T , A : Allocator > ( elem : T , n : usize , alloc : A ) -> Vec < T , A > {
3206+ /// # Safety
3207+ ///
3208+ /// `value` must points to a valid `T` value that is the result of some const expression.
3209+ unsafe fn fill_const_value < T > ( buffer : & mut [ MaybeUninit < T > ] , value : * const T ) {
3210+ for target in buffer {
3211+ // SAFETY: If `value` is the result of some const expression, we can make as many
3212+ // copies as needed.
3213+ unsafe { target. write ( ptr:: read ( value) ) } ;
3214+ }
3215+ }
3216+
3217+ // Avoid calling the destructor of `elem`.
3218+ let elem = ManuallyDrop :: new ( elem) ;
3219+ let elem_ptr = ptr:: from_ref ( & * elem) ;
3220+ let mut result = Vec :: < T , A > :: with_capacity_in ( n, alloc) ;
3221+ let buffer_ptr = result. as_mut_ptr ( ) . cast :: < MaybeUninit < T > > ( ) ;
3222+
3223+ // SAFETY: `with_capacity_in` makes sure the capacity is at least `n`, so we can make a buffer
3224+ // of length `n` out of it.
3225+ let buffer = unsafe { slice:: from_raw_parts_mut ( buffer_ptr, n) } ;
3226+
3227+ // SAFETY: Caller has guaranteed `elem` being the result of some const expression.
3228+ unsafe { fill_const_value ( buffer, elem_ptr) } ;
3229+
3230+ // SAFETY: We have initialized exactly `n` values at the start of the buffer, so we are safe to
3231+ // set the length accordingly.
3232+ unsafe { result. set_len ( n) } ;
3233+
3234+ result
3235+ }
3236+
31863237#[ cfg( not( no_global_oom_handling) ) ]
31873238trait ExtendFromWithinSpec {
31883239 /// # Safety
0 commit comments