@@ -2014,7 +2014,7 @@ impl<T, I: SliceIndex<[T]>> IndexMut<I> for Vec<T> {
20142014impl < T > FromIterator < T > for Vec < T > {
20152015 #[ inline]
20162016 fn from_iter < I : IntoIterator < Item = T > > ( iter : I ) -> Vec < T > {
2017- <Self as SpecFrom < T , I :: IntoIter > >:: from_iter ( iter. into_iter ( ) )
2017+ <Self as SpecFromIter < T , I :: IntoIter > >:: from_iter ( iter. into_iter ( ) )
20182018 }
20192019}
20202020
@@ -2096,18 +2096,39 @@ impl<T> Extend<T> for Vec<T> {
20962096 }
20972097}
20982098
2099- // Specialization trait used for Vec::from_iter
2100- trait SpecFrom < T , I > {
2099+ /// Specialization trait used for Vec::from_iter
2100+ ///
2101+ /// ## The delegation graph:
2102+ ///
2103+ /// ```text
2104+ /// +-------------+
2105+ /// |FromIterator |
2106+ /// +-+-----------+
2107+ /// |
2108+ /// v
2109+ /// +-+-------------------------------+ +---------------------+
2110+ /// |SpecFromIter +---->+SpecFromIterNested |
2111+ /// |where I: | | |where I: |
2112+ /// | Iterator (default)----------+ | | Iterator (default) |
2113+ /// | vec::IntoIter | | | TrustedLen |
2114+ /// | SourceIterMarker---fallback-+ | | |
2115+ /// | slice::Iter | | |
2116+ /// | Iterator<Item = &Clone> | +---------------------+
2117+ /// +---------------------------------+
2118+ ///
2119+ /// ```
2120+ trait SpecFromIter < T , I > {
21012121 fn from_iter ( iter : I ) -> Self ;
21022122}
21032123
2104- // Another specialization trait for Vec::from_iter
2105- // necessary to manually prioritize overlapping specializations
2106- trait SpecFromNested < T , I > {
2124+ /// Another specialization trait for Vec::from_iter
2125+ /// necessary to manually prioritize overlapping specializations
2126+ /// see [`SpecFromIter`] for details.
2127+ trait SpecFromIterNested < T , I > {
21072128 fn from_iter ( iter : I ) -> Self ;
21082129}
21092130
2110- impl < T , I > SpecFromNested < T , I > for Vec < T >
2131+ impl < T , I > SpecFromIterNested < T , I > for Vec < T >
21112132where
21122133 I : Iterator < Item = T > ,
21132134{
@@ -2136,7 +2157,7 @@ where
21362157 }
21372158}
21382159
2139- impl < T , I > SpecFromNested < T , I > for Vec < T >
2160+ impl < T , I > SpecFromIterNested < T , I > for Vec < T >
21402161where
21412162 I : TrustedLen < Item = T > ,
21422163{
@@ -2149,12 +2170,12 @@ where
21492170 }
21502171}
21512172
2152- impl < T , I > SpecFrom < T , I > for Vec < T >
2173+ impl < T , I > SpecFromIter < T , I > for Vec < T >
21532174where
21542175 I : Iterator < Item = T > ,
21552176{
21562177 default fn from_iter ( iterator : I ) -> Self {
2157- SpecFromNested :: from_iter ( iterator)
2178+ SpecFromIterNested :: from_iter ( iterator)
21582179 }
21592180}
21602181
@@ -2182,18 +2203,21 @@ impl<T> Drop for InPlaceDrop<T> {
21822203 }
21832204}
21842205
2185- impl < T > SpecFrom < T , IntoIter < T > > for Vec < T > {
2206+ impl < T > SpecFromIter < T , IntoIter < T > > for Vec < T > {
21862207 fn from_iter ( iterator : IntoIter < T > ) -> Self {
21872208 // A common case is passing a vector into a function which immediately
21882209 // re-collects into a vector. We can short circuit this if the IntoIter
21892210 // has not been advanced at all.
2190- // We can also reuse the memory and move the data to the front if
2191- // allocating a new vector and moving to it would result in the same capacity
2192- let non_zero_offset = iterator. buf . as_ptr ( ) as * const _ != iterator. ptr ;
2193- if !non_zero_offset || iterator. len ( ) >= iterator. cap / 2 {
2211+ // When it has been advanced We can also reuse the memory and move the data to the front.
2212+ // But we only do so when the resulting Vec wouldn't have more unused capacity
2213+ // than creating it through the generic FromIterator implementation would. That limitation
2214+ // is not strictly necessary as Vec's allocation behavior is intentionally unspecified.
2215+ // But it is a conservative choice.
2216+ let has_advanced = iterator. buf . as_ptr ( ) as * const _ != iterator. ptr ;
2217+ if !has_advanced || iterator. len ( ) >= iterator. cap / 2 {
21942218 unsafe {
21952219 let it = ManuallyDrop :: new ( iterator) ;
2196- if non_zero_offset {
2220+ if has_advanced {
21972221 ptr:: copy ( it. ptr , it. buf . as_ptr ( ) , it. len ( ) ) ;
21982222 }
21992223 return Vec :: from_raw_parts ( it. buf . as_ptr ( ) , it. len ( ) , it. cap ) ;
@@ -2224,6 +2248,12 @@ fn write_in_place_with_drop<T>(
22242248 }
22252249}
22262250
2251+ /// Specialization marker for collecting an iterator pipeline into a Vec while reusing the
2252+ /// source allocation, i.e. executing the pipeline in place.
2253+ ///
2254+ /// The SourceIter parent trait is necessary for the specializing function to access the allocation
2255+ /// which is to be reused. But it is not sufficient for the specialization to be valid. See
2256+ /// additional bounds on the impl.
22272257#[ rustc_unsafe_specialization_marker]
22282258trait SourceIterMarker : SourceIter < Source : AsIntoIter > { }
22292259
@@ -2235,7 +2265,7 @@ trait SourceIterMarker: SourceIter<Source: AsIntoIter> {}
22352265// several other specializations already depend on.
22362266impl < T > SourceIterMarker for T where T : SourceIter < Source : AsIntoIter > + InPlaceIterable { }
22372267
2238- impl < T , I > SpecFrom < T , I > for Vec < T >
2268+ impl < T , I > SpecFromIter < T , I > for Vec < T >
22392269where
22402270 I : Iterator < Item = T > + SourceIterMarker ,
22412271{
@@ -2251,7 +2281,8 @@ where
22512281 || mem:: align_of :: < T > ( )
22522282 != mem:: align_of :: < <<I as SourceIter >:: Source as AsIntoIter >:: Item > ( )
22532283 {
2254- return SpecFromNested :: from_iter ( iterator) ;
2284+ // fallback to more generic implementations
2285+ return SpecFromIterNested :: from_iter ( iterator) ;
22552286 }
22562287
22572288 let ( src_buf, dst_buf, dst_end, cap) = unsafe {
@@ -2277,9 +2308,9 @@ where
22772308 debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
22782309
22792310 // drop any remaining values at the tail of the source
2280- src. drop_in_place ( ) ;
2311+ src. drop_remaining ( ) ;
22812312 // but prevent drop of the allocation itself once IntoIter goes out of scope
2282- src. forget_in_place ( ) ;
2313+ src. forget_allocation ( ) ;
22832314
22842315 let vec = unsafe {
22852316 let len = dst. offset_from ( dst_buf) as usize ;
@@ -2290,17 +2321,17 @@ where
22902321 }
22912322}
22922323
2293- impl < ' a , T : ' a , I > SpecFrom < & ' a T , I > for Vec < T >
2324+ impl < ' a , T : ' a , I > SpecFromIter < & ' a T , I > for Vec < T >
22942325where
22952326 I : Iterator < Item = & ' a T > ,
22962327 T : Clone ,
22972328{
22982329 default fn from_iter ( iterator : I ) -> Self {
2299- SpecFrom :: from_iter ( iterator. cloned ( ) )
2330+ SpecFromIter :: from_iter ( iterator. cloned ( ) )
23002331 }
23012332}
23022333
2303- impl < ' a , T : ' a > SpecFrom < & ' a T , slice:: Iter < ' a , T > > for Vec < T >
2334+ impl < ' a , T : ' a > SpecFromIter < & ' a T , slice:: Iter < ' a , T > > for Vec < T >
23042335where
23052336 T : Copy ,
23062337{
@@ -2824,7 +2855,7 @@ impl<T> IntoIter<T> {
28242855 ptr:: slice_from_raw_parts_mut ( self . ptr as * mut T , self . len ( ) )
28252856 }
28262857
2827- fn drop_in_place ( & mut self ) {
2858+ fn drop_remaining ( & mut self ) {
28282859 if mem:: needs_drop :: < T > ( ) {
28292860 unsafe {
28302861 ptr:: drop_in_place ( self . as_mut_slice ( ) ) ;
@@ -2835,7 +2866,7 @@ impl<T> IntoIter<T> {
28352866
28362867 /// Relinquishes the backing allocation, equivalent to
28372868 /// `ptr::write(&mut self, Vec::new().into_iter())`
2838- fn forget_in_place ( & mut self ) {
2869+ fn forget_allocation ( & mut self ) {
28392870 self . cap = 0 ;
28402871 self . buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
28412872 self . ptr = self . buf . as_ptr ( ) ;
0 commit comments