@@ -2561,7 +2561,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
25612561 let len = self . len ( ) ;
25622562
25632563 if new_len > len {
2564- self . extend_with ( new_len - len, value )
2564+ self . extend_trusted ( core :: iter :: repeat_n ( value , new_len - len) ) ;
25652565 } else {
25662566 self . truncate ( new_len) ;
25672567 }
@@ -2673,38 +2673,6 @@ impl<T, A: Allocator, const N: usize> Vec<[T; N], A> {
26732673 }
26742674}
26752675
2676- impl < T : Clone , A : Allocator > Vec < T , A > {
2677- #[ cfg( not( no_global_oom_handling) ) ]
2678- /// Extend the vector by `n` clones of value.
2679- fn extend_with ( & mut self , n : usize , value : T ) {
2680- self . reserve ( n) ;
2681-
2682- unsafe {
2683- let mut ptr = self . as_mut_ptr ( ) . add ( self . len ( ) ) ;
2684- // Use SetLenOnDrop to work around bug where compiler
2685- // might not realize the store through `ptr` through self.set_len()
2686- // don't alias.
2687- let mut local_len = SetLenOnDrop :: new ( & mut self . len ) ;
2688-
2689- // Write all elements except the last one
2690- for _ in 1 ..n {
2691- ptr:: write ( ptr, value. clone ( ) ) ;
2692- ptr = ptr. add ( 1 ) ;
2693- // Increment the length in every step in case clone() panics
2694- local_len. increment_len ( 1 ) ;
2695- }
2696-
2697- if n > 0 {
2698- // We can write the last element directly without cloning needlessly
2699- ptr:: write ( ptr, value) ;
2700- local_len. increment_len ( 1 ) ;
2701- }
2702-
2703- // len set by scope guard
2704- }
2705- }
2706- }
2707-
27082676impl < T : PartialEq , A : Allocator > Vec < T , A > {
27092677 /// Removes consecutive repeated elements in the vector according to the
27102678 /// [`PartialEq`] trait implementation.
@@ -3083,32 +3051,36 @@ impl<T, A: Allocator> Vec<T, A> {
30833051 #[ cfg( not( no_global_oom_handling) ) ]
30843052 fn extend_trusted ( & mut self , iterator : impl iter:: TrustedLen < Item = T > ) {
30853053 let ( low, high) = iterator. size_hint ( ) ;
3086- if let Some ( additional) = high {
3087- debug_assert_eq ! (
3088- low,
3089- additional,
3090- "TrustedLen iterator's size hint is not exact: {:?}" ,
3091- ( low, high)
3092- ) ;
3093- self . reserve ( additional) ;
3094- unsafe {
3095- let ptr = self . as_mut_ptr ( ) ;
3096- let mut local_len = SetLenOnDrop :: new ( & mut self . len ) ;
3097- iterator. for_each ( move |element| {
3098- ptr:: write ( ptr. add ( local_len. current_len ( ) ) , element) ;
3099- // Since the loop executes user code which can panic we have to update
3100- // the length every step to correctly drop what we've written.
3101- // NB can't overflow since we would have had to alloc the address space
3102- local_len. increment_len ( 1 ) ;
3103- } ) ;
3104- }
3105- } else {
3054+ if high. is_none ( ) {
31063055 // Per TrustedLen contract a `None` upper bound means that the iterator length
31073056 // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway.
31083057 // Since the other branch already panics eagerly (via `reserve()`) we do the same here.
31093058 // This avoids additional codegen for a fallback code path which would eventually
31103059 // panic anyway.
31113060 panic ! ( "capacity overflow" ) ;
3061+ } ;
3062+
3063+ debug_assert_eq ! (
3064+ Some ( low) ,
3065+ high,
3066+ "TrustedLen iterator's size hint is not exact: {:?}" ,
3067+ ( low, high)
3068+ ) ;
3069+ self . reserve ( low) ;
3070+
3071+ // SAFETY: From TrustedLen we know exactly how many slots we'll need,
3072+ // and we just reserved them. Thus we can write each element as we generate
3073+ // it into its final location without needing any further safety checks.
3074+ unsafe {
3075+ let ptr = self . as_mut_ptr ( ) ;
3076+ let mut local_len = SetLenOnDrop :: new ( & mut self . len ) ;
3077+ iterator. for_each ( move |element| {
3078+ ptr:: write ( ptr. add ( local_len. current_len ( ) ) , element) ;
3079+ // Since the loop executes user code which can panic we have to update
3080+ // the length every step to correctly drop what we've written.
3081+ // NB can't overflow since we would have had to alloc the address space
3082+ local_len. increment_len_unchecked ( 1 ) ;
3083+ } ) ;
31123084 }
31133085 }
31143086
0 commit comments