@@ -2188,83 +2188,6 @@ impl<T> Drop for InPlaceDrop<T> {
2188
2188
}
2189
2189
}
2190
2190
2191
- fn from_into_iter_source < T , I > ( mut iterator : I ) -> Vec < T >
2192
- where
2193
- I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source = IntoIter < T > > ,
2194
- {
2195
- // This specialization only makes sense if we're juggling real allocations.
2196
- // Additionally some of the pointer arithmetic would panic on ZSTs.
2197
- if mem:: size_of :: < T > ( ) == 0 {
2198
- return SpecFromNested :: from_iter ( iterator) ;
2199
- }
2200
-
2201
- let src_buf = iterator. as_inner ( ) . buf . as_ptr ( ) ;
2202
- let src_end = iterator. as_inner ( ) . end ;
2203
- let dst = src_buf;
2204
-
2205
- let dst = if mem:: needs_drop :: < T > ( ) {
2206
- // special-case drop handling since it prevents vectorization
2207
- let mut sink = InPlaceDrop { inner : src_buf, dst, did_panic : true } ;
2208
- let _ = iterator. try_for_each :: < _ , Result < _ , !> > ( |item| {
2209
- unsafe {
2210
- debug_assert ! (
2211
- sink. dst as * const _ <= src_end,
2212
- "InPlaceIterable contract violation"
2213
- ) ;
2214
- ptr:: write ( sink. dst , item) ;
2215
- sink. dst = sink. dst . add ( 1 ) ;
2216
- }
2217
- Ok ( ( ) )
2218
- } ) ;
2219
- sink. did_panic = false ;
2220
- sink. dst
2221
- } else {
2222
- // use try-fold
2223
- // - it vectorizes better
2224
- // - unlike most internal iteration methods methods it only takes a &mut self
2225
- // - lets us thread the write pointer through its innards and get it back in the end
2226
- iterator
2227
- . try_fold :: < _ , _ , Result < _ , !> > ( dst, move |mut dst, item| {
2228
- unsafe {
2229
- // the InPlaceIterable contract cannot be verified precisely here since
2230
- // try_fold has an exclusive reference to the source pointer
2231
- // all we can do is check if it's still in range
2232
- debug_assert ! ( dst as * const _ <= src_end, "InPlaceIterable contract violation" ) ;
2233
- ptr:: write ( dst, item) ;
2234
- dst = dst. add ( 1 ) ;
2235
- }
2236
- Ok ( dst)
2237
- } )
2238
- . unwrap ( )
2239
- } ;
2240
-
2241
- let src = iterator. as_inner ( ) ;
2242
- // check if SourceIter and InPlaceIterable contracts were upheld.
2243
- // caveat: if they weren't we may not even make it to this point
2244
- debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
2245
- debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
2246
-
2247
- if mem:: needs_drop :: < T > ( ) {
2248
- // drop tail if iterator was only partially exhaused
2249
- unsafe {
2250
- ptr:: drop_in_place ( src. as_mut_slice ( ) ) ;
2251
- }
2252
- }
2253
-
2254
- let vec = unsafe {
2255
- let len = dst. offset_from ( src_buf) as usize ;
2256
- Vec :: from_raw_parts ( src. buf . as_ptr ( ) , len, src. cap )
2257
- } ;
2258
- // prevent drop of the underlying storage by turning the IntoIter into
2259
- // the equivalent of Vec::new().into_iter()
2260
- src. cap = 0 ;
2261
- src. buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2262
- src. ptr = src. buf . as_ptr ( ) ;
2263
- src. end = src. buf . as_ptr ( ) ;
2264
-
2265
- vec
2266
- }
2267
-
2268
2191
impl < T > SpecFrom < T , IntoIter < T > > for Vec < T > {
2269
2192
fn from_iter ( iterator : IntoIter < T > ) -> Self {
2270
2193
// A common case is passing a vector into a function which immediately
@@ -2298,8 +2221,81 @@ impl<T, I> SpecFrom<T, I> for Vec<T>
2298
2221
where
2299
2222
I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source = IntoIter < T > > ,
2300
2223
{
2301
- default fn from_iter ( iterator : I ) -> Self {
2302
- from_into_iter_source ( iterator)
2224
+ default fn from_iter ( mut iterator : I ) -> Self {
2225
+ // This specialization only makes sense if we're juggling real allocations.
2226
+ // Additionally some of the pointer arithmetic would panic on ZSTs.
2227
+ if mem:: size_of :: < T > ( ) == 0 {
2228
+ return SpecFromNested :: from_iter ( iterator) ;
2229
+ }
2230
+
2231
+ let src_buf = iterator. as_inner ( ) . buf . as_ptr ( ) ;
2232
+ let src_end = iterator. as_inner ( ) . end ;
2233
+ let dst = src_buf;
2234
+
2235
+ let dst = if mem:: needs_drop :: < T > ( ) {
2236
+ // special-case drop handling since it prevents vectorization
2237
+ let mut sink = InPlaceDrop { inner : src_buf, dst, did_panic : true } ;
2238
+ let _ = iterator. try_for_each :: < _ , Result < _ , !> > ( |item| {
2239
+ unsafe {
2240
+ debug_assert ! (
2241
+ sink. dst as * const _ <= src_end,
2242
+ "InPlaceIterable contract violation"
2243
+ ) ;
2244
+ ptr:: write ( sink. dst , item) ;
2245
+ sink. dst = sink. dst . add ( 1 ) ;
2246
+ }
2247
+ Ok ( ( ) )
2248
+ } ) ;
2249
+ sink. did_panic = false ;
2250
+ sink. dst
2251
+ } else {
2252
+ // use try-fold
2253
+ // - it vectorizes better
2254
+ // - unlike most internal iteration methods methods it only takes a &mut self
2255
+ // - lets us thread the write pointer through its innards and get it back in the end
2256
+ iterator
2257
+ . try_fold :: < _ , _ , Result < _ , !> > ( dst, move |mut dst, item| {
2258
+ unsafe {
2259
+ // the InPlaceIterable contract cannot be verified precisely here since
2260
+ // try_fold has an exclusive reference to the source pointer
2261
+ // all we can do is check if it's still in range
2262
+ debug_assert ! (
2263
+ dst as * const _ <= src_end,
2264
+ "InPlaceIterable contract violation"
2265
+ ) ;
2266
+ ptr:: write ( dst, item) ;
2267
+ dst = dst. add ( 1 ) ;
2268
+ }
2269
+ Ok ( dst)
2270
+ } )
2271
+ . unwrap ( )
2272
+ } ;
2273
+
2274
+ let src = iterator. as_inner ( ) ;
2275
+ // check if SourceIter and InPlaceIterable contracts were upheld.
2276
+ // caveat: if they weren't we may not even make it to this point
2277
+ debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
2278
+ debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
2279
+
2280
+ if mem:: needs_drop :: < T > ( ) {
2281
+ // drop tail if iterator was only partially exhaused
2282
+ unsafe {
2283
+ ptr:: drop_in_place ( src. as_mut_slice ( ) ) ;
2284
+ }
2285
+ }
2286
+
2287
+ let vec = unsafe {
2288
+ let len = dst. offset_from ( src_buf) as usize ;
2289
+ Vec :: from_raw_parts ( src. buf . as_ptr ( ) , len, src. cap )
2290
+ } ;
2291
+ // prevent drop of the underlying storage by turning the IntoIter into
2292
+ // the equivalent of Vec::new().into_iter()
2293
+ src. cap = 0 ;
2294
+ src. buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2295
+ src. ptr = src. buf . as_ptr ( ) ;
2296
+ src. end = src. buf . as_ptr ( ) ;
2297
+
2298
+ vec
2303
2299
}
2304
2300
}
2305
2301
0 commit comments