@@ -2414,18 +2414,7 @@ impl<T, A: Allocator> Vec<T, A> {
24142414 #[ rustc_confusables( "push_back" , "put" , "append" ) ]
24152415 #[ track_caller]
24162416 pub fn push ( & mut self , value : T ) {
2417- // Inform codegen that the length does not change across grow_one().
2418- let len = self . len ;
2419- // This will panic or abort if we would allocate > isize::MAX bytes
2420- // or if the length increment would overflow for zero-sized types.
2421- if len == self . buf . capacity ( ) {
2422- self . buf . grow_one ( ) ;
2423- }
2424- unsafe {
2425- let end = self . as_mut_ptr ( ) . add ( len) ;
2426- ptr:: write ( end, value) ;
2427- self . len = len + 1 ;
2428- }
2417+ let _ = self . push_mut ( value) ;
24292418 }
24302419
24312420 /// Appends an element if there is sufficient spare capacity, otherwise an error is returned
@@ -2466,15 +2455,83 @@ impl<T, A: Allocator> Vec<T, A> {
24662455 #[ inline]
24672456 #[ unstable( feature = "vec_push_within_capacity" , issue = "100486" ) ]
24682457 pub fn push_within_capacity ( & mut self , value : T ) -> Result < ( ) , T > {
2458+ self . push_mut_within_capacity ( value) . map ( |_| ( ) )
2459+ }
2460+
2461+ /// Appends an element to the back of a collection, returning a reference to it.
2462+ ///
2463+ /// # Panics
2464+ ///
2465+ /// Panics if the new capacity exceeds `isize::MAX` _bytes_.
2466+ ///
2467+ /// # Examples
2468+ ///
2469+ /// ```
2470+ /// #![feature(push_mut)]
2471+ ///
2472+ /// let mut vec = vec![];
2473+ /// // Polonius moment.
2474+ /// let last = if let Some(v) = vec.last_mut() { v } else { vec.push_mut(0) };
2475+ /// *last += 6;
2476+ /// assert_eq!(vec, [6]);
2477+ /// ```
2478+ ///
2479+ /// # Time complexity
2480+ ///
2481+ /// Takes amortized *O*(1) time. If the vector's length would exceed its
2482+ /// capacity after the push, *O*(*capacity*) time is taken to copy the
2483+ /// vector's elements to a larger allocation. This expensive operation is
2484+ /// offset by the *capacity* *O*(1) insertions it allows.
2485+ #[ cfg( not( no_global_oom_handling) ) ]
2486+ #[ inline]
2487+ #[ unstable( feature = "push_mut" , issue = "none" ) ]
2488+ #[ track_caller]
2489+ #[ must_use = "if you don't need a reference to the value, use Vec::push instead" ]
2490+ pub fn push_mut ( & mut self , value : T ) -> & mut T {
2491+ // Inform codegen that the length does not change across grow_one().
2492+ let len = self . len ;
2493+ // This will panic or abort if we would allocate > isize::MAX bytes
2494+ // or if the length increment would overflow for zero-sized types.
2495+ if len == self . buf . capacity ( ) {
2496+ self . buf . grow_one ( ) ;
2497+ }
2498+ unsafe {
2499+ let end = self . as_mut_ptr ( ) . add ( len) ;
2500+ ptr:: write ( end, value) ;
2501+ self . len = len + 1 ;
2502+ // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference.
2503+ & mut * end
2504+ }
2505+ }
2506+
2507+ /// Appends an element and returns a reference to it if there is sufficient spare capacity, otherwise an error is returned
2508+ /// with the element.
2509+ ///
2510+ /// Unlike [`push_mut`] this method will not reallocate when there's insufficient capacity.
2511+ /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity.
2512+ ///
2513+ /// [`push_mut`]: Vec::push_mut
2514+ /// [`reserve`]: Vec::reserve
2515+ /// [`try_reserve`]: Vec::try_reserve
2516+ ///
2517+ /// # Time complexity
2518+ ///
2519+ /// Takes *O*(1) time.
2520+ #[ inline]
2521+ #[ unstable( feature = "push_mut" , issue = "none" ) ]
2522+ #[ must_use = "if you don't need a reference to the value, use Vec::push_within_capacity instead" ]
2523+ // #[unstable(feature = "vec_push_within_capacity", issue = "100486")]
2524+ pub fn push_mut_within_capacity ( & mut self , value : T ) -> Result < & mut T , T > {
24692525 if self . len == self . buf . capacity ( ) {
24702526 return Err ( value) ;
24712527 }
24722528 unsafe {
24732529 let end = self . as_mut_ptr ( ) . add ( self . len ) ;
24742530 ptr:: write ( end, value) ;
24752531 self . len += 1 ;
2532+ // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference.
2533+ Ok ( & mut * end)
24762534 }
2477- Ok ( ( ) )
24782535 }
24792536
24802537 /// Removes the last element from a vector and returns it, or [`None`] if it
0 commit comments