@@ -2870,6 +2870,41 @@ impl<T, A: Allocator> Vec<T, A> {
2870
2870
}
2871
2871
}
2872
2872
2873
+ // specific extend for `TrustedLen` iterators, called both by the specializations
2874
+ // and internal places where resolving specialization makes compilation slower
2875
+ #[ cfg( not( no_global_oom_handling) ) ]
2876
+ fn extend_trusted ( & mut self , iterator : impl iter:: TrustedLen < Item = T > ) {
2877
+ let ( low, high) = iterator. size_hint ( ) ;
2878
+ if let Some ( additional) = high {
2879
+ debug_assert_eq ! (
2880
+ low,
2881
+ additional,
2882
+ "TrustedLen iterator's size hint is not exact: {:?}" ,
2883
+ ( low, high)
2884
+ ) ;
2885
+ self . reserve ( additional) ;
2886
+ unsafe {
2887
+ let mut ptr = self . as_mut_ptr ( ) . add ( self . len ( ) ) ;
2888
+ let mut local_len = SetLenOnDrop :: new ( & mut self . len ) ;
2889
+ iterator. for_each ( move |element| {
2890
+ ptr:: write ( ptr, element) ;
2891
+ ptr = ptr. add ( 1 ) ;
2892
+ // Since the loop executes user code which can panic we have to bump the pointer
2893
+ // after each step.
2894
+ // NB can't overflow since we would have had to alloc the address space
2895
+ local_len. increment_len ( 1 ) ;
2896
+ } ) ;
2897
+ }
2898
+ } else {
2899
+ // Per TrustedLen contract a `None` upper bound means that the iterator length
2900
+ // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway.
2901
+ // Since the other branch already panics eagerly (via `reserve()`) we do the same here.
2902
+ // This avoids additional codegen for a fallback code path which would eventually
2903
+ // panic anyway.
2904
+ panic ! ( "capacity overflow" ) ;
2905
+ }
2906
+ }
2907
+
2873
2908
/// Creates a splicing iterator that replaces the specified range in the vector
2874
2909
/// with the given `replace_with` iterator and yields the removed items.
2875
2910
/// `replace_with` does not need to be the same length as `range`.
0 commit comments