@@ -3183,6 +3183,57 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
3183
3183
<T as SpecFromElem >:: from_elem ( elem, n, alloc)
3184
3184
}
3185
3185
3186
+ /// # Safety
3187
+ ///
3188
+ /// `value` must points to a valid `T` value that is the result of some const expression.
3189
+ unsafe fn fill_const_value < T > ( buffer : & mut [ MaybeUninit < T > ] , value : * const T ) {
3190
+ for target in buffer {
3191
+ // SAFETY: If `value` is the result of some const expression, we can make as many copies as
3192
+ // needed.
3193
+ unsafe { target. write ( ptr:: read ( value) ) } ;
3194
+ }
3195
+ }
3196
+
3197
+ /// # Safety
3198
+ ///
3199
+ /// `elem` must be the result of some const expression.
3200
+ #[ doc( hidden) ]
3201
+ #[ cfg( not( no_global_oom_handling) ) ]
3202
+ #[ unstable( feature = "vec_of_const_expr" , issue = "none" ) ]
3203
+ #[ track_caller]
3204
+ pub unsafe fn from_const_elem < T > ( elem : T , n : usize ) -> Vec < T > {
3205
+ // SAFETY: Caller has guaranteed `elem` being the result of some const expression.
3206
+ unsafe { from_const_elem_in ( elem, n, Global ) }
3207
+ }
3208
+
3209
+ /// # Safety
3210
+ ///
3211
+ /// `elem` must be the result of some const expression.
3212
+ #[ doc( hidden) ]
3213
+ #[ cfg( not( no_global_oom_handling) ) ]
3214
+ #[ unstable( feature = "vec_of_const_expr" , issue = "none" ) ]
3215
+ #[ track_caller]
3216
+ unsafe fn from_const_elem_in < T , A : Allocator > ( elem : T , n : usize , alloc : A ) -> Vec < T , A > {
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
+
3186
3237
#[ cfg( not( no_global_oom_handling) ) ]
3187
3238
trait ExtendFromWithinSpec {
3188
3239
/// # Safety
0 commit comments