@@ -2114,8 +2114,7 @@ impl<A: Allocator> RawVecInner<A> {
21142114 /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to
21152115 /// initially construct `self`
21162116 /// - `elem_layout`'s size must be a multiple of its alignment
2117- /// - The sum of `len` and `additional` must be greater than or equal to
2118- /// `self.capacity(elem_layout.size())`
2117+ /// - The sum of `len` and `additional` must be greater than the current capacity
21192118 unsafe fn grow_amortized (
21202119 & mut self ,
21212120 len : usize ,
@@ -2246,8 +2245,7 @@ impl<A: Allocator> RawVecInner<A> {
22462245 /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to
22472246 /// initially construct `self`
22482247 /// - `elem_layout`'s size must be a multiple of its alignment
2249- /// - The sum of `len` and `additional` must be greater than or equal to
2250- /// `self.capacity(elem_layout.size())`
2248+ /// - The sum of `len` and `additional` must be greater than the current capacity
22512249 unsafe fn grow_exact (
22522250 & mut self ,
22532251 len : usize ,
@@ -2288,7 +2286,6 @@ impl<A: Allocator> RawVecInner<A> {
22882286 //@ close <std::collections::TryReserveErrorKind>.own(t, std::collections::TryReserveErrorKind::CapacityOverflow);
22892287 let cap = len. checked_add ( additional) . ok_or ( CapacityOverflow ) ?;
22902288 //@ leak <std::collections::TryReserveErrorKind>.own(t, std::collections::TryReserveErrorKind::CapacityOverflow);
2291- let new_layout = layout_array ( cap, elem_layout) ?;
22922289 //@ std::alloc::Layout_repeat_some_size_aligned(elem_layout, cap);
22932290
22942291 //@ let k = begin_lifetime();
@@ -2307,6 +2304,35 @@ impl<A: Allocator> RawVecInner<A> {
23072304
23082305 //@ open RawVecInner(t, *self, elem_layout, alloc_id, ptr0, capacity0);
23092306 //@ let ptr0_ = (*self).ptr;
2307+ /// - `cap` must be greater than the current capacity
2308+ // not marked inline(never) since we want optimizers to be able to observe the specifics of this
2309+ // function, see tests/codegen-llvm/vec-reserve-extend.rs.
2310+ #[ cold]
2311+ unsafe fn finish_grow (
2312+ & self ,
2313+ cap : usize ,
2314+ elem_layout : Layout ,
2315+ ) -> Result < NonNull < [ u8 ] > , TryReserveError > {
2316+ let new_layout = layout_array ( cap, elem_layout) ?;
2317+
2318+ let memory = if let Some ( ( ptr, old_layout) ) = unsafe { self . current_memory ( elem_layout) } {
2319+ debug_assert_eq ! ( old_layout. align( ) , new_layout. align( ) ) ;
2320+ unsafe {
2321+ // The allocator checks for alignment equality
2322+ hint:: assert_unchecked ( old_layout. align ( ) == new_layout. align ( ) ) ;
2323+ self . alloc . grow ( ptr, old_layout, new_layout)
2324+ }
2325+ } else {
2326+ self . alloc . allocate ( new_layout)
2327+ } ;
2328+
2329+ memory. map_err ( |_| AllocError { layout : new_layout, non_exhaustive : ( ) } . into ( ) )
2330+ }
2331+
2332+ /// # Safety
2333+ /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to
2334+ /// initially construct `self`
2335+ /// - `elem_layout`'s size must be a multiple of its alignment
23102336 //@ let cap0_ = (*self).cap;
23112337 //@ assert ptr0_.as_non_null_ptr().as_ptr() == ptr0;
23122338 //@ std::alloc::Layout_inv(elem_layout);
0 commit comments