@@ -2561,7 +2561,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
2561
2561
let len = self . len ( ) ;
2562
2562
2563
2563
if new_len > len {
2564
- self . extend_with ( new_len - len, value )
2564
+ self . extend_trusted ( core :: iter :: repeat_n ( value , new_len - len) ) ;
2565
2565
} else {
2566
2566
self . truncate ( new_len) ;
2567
2567
}
@@ -2673,38 +2673,6 @@ impl<T, A: Allocator, const N: usize> Vec<[T; N], A> {
2673
2673
}
2674
2674
}
2675
2675
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
-
2708
2676
impl < T : PartialEq , A : Allocator > Vec < T , A > {
2709
2677
/// Removes consecutive repeated elements in the vector according to the
2710
2678
/// [`PartialEq`] trait implementation.
@@ -3083,32 +3051,36 @@ impl<T, A: Allocator> Vec<T, A> {
3083
3051
#[ cfg( not( no_global_oom_handling) ) ]
3084
3052
fn extend_trusted ( & mut self , iterator : impl iter:: TrustedLen < Item = T > ) {
3085
3053
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 ( ) {
3106
3055
// Per TrustedLen contract a `None` upper bound means that the iterator length
3107
3056
// truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway.
3108
3057
// Since the other branch already panics eagerly (via `reserve()`) we do the same here.
3109
3058
// This avoids additional codegen for a fallback code path which would eventually
3110
3059
// panic anyway.
3111
3060
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
+ } ) ;
3112
3084
}
3113
3085
}
3114
3086
0 commit comments