@@ -2240,23 +2240,28 @@ fn write_in_place_with_drop<T>(
2240
2240
}
2241
2241
}
2242
2242
2243
- // Further specialization potential once
2244
- // https://github.com/rust-lang/rust/issues/62645 has been solved:
2245
- // T can be split into IN and OUT which only need to have the same size and alignment
2246
2243
impl < T , I > SpecFrom < T , I > for Vec < T >
2247
2244
where
2248
- I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter < T > > ,
2245
+ I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter > ,
2249
2246
{
2250
2247
default fn from_iter ( mut iterator : I ) -> Self {
2251
- // This specialization only makes sense if we're juggling real allocations.
2252
- // Additionally some of the pointer arithmetic would panic on ZSTs.
2253
- if mem:: size_of :: < T > ( ) == 0 {
2248
+ // Additional requirements which cannot expressed via trait bounds. We rely on const eval
2249
+ // instead:
2250
+ // a) no ZSTs as there would be no allocation to reuse and pointer arithmetic would panic
2251
+ // b) size match as required by Alloc contract
2252
+ // c) alignments match as required by Alloc contract
2253
+ if mem:: size_of :: < T > ( ) == 0
2254
+ || mem:: size_of :: < T > ( )
2255
+ != mem:: size_of :: < <<I as SourceIter >:: Source as AsIntoIter >:: Item > ( )
2256
+ || mem:: align_of :: < T > ( )
2257
+ != mem:: align_of :: < <<I as SourceIter >:: Source as AsIntoIter >:: Item > ( )
2258
+ {
2254
2259
return SpecFromNested :: from_iter ( iterator) ;
2255
2260
}
2256
2261
2257
- let ( src_buf, src_end , cap) = {
2258
- let inner = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
2259
- ( inner. buf . as_ptr ( ) , inner. end , inner. cap )
2262
+ let ( src_buf, dst_buf , dst_end , cap) = unsafe {
2263
+ let inner = iterator. as_inner ( ) . as_into_iter ( ) ;
2264
+ ( inner. buf . as_ptr ( ) , inner. buf . as_ptr ( ) as * mut T , inner . end as * const T , inner. cap )
2260
2265
} ;
2261
2266
2262
2267
// use try-fold
@@ -2266,15 +2271,15 @@ where
2266
2271
let dst = if mem:: needs_drop :: < T > ( ) {
2267
2272
// special-case drop handling since it forces us to lug that extra field around which
2268
2273
// can inhibit optimizations
2269
- let sink = InPlaceDrop { inner : src_buf , dst : src_buf } ;
2274
+ let sink = InPlaceDrop { inner : dst_buf , dst : dst_buf } ;
2270
2275
let sink = iterator
2271
- . try_fold :: < _ , _ , Result < _ , !> > ( sink, write_in_place_with_drop ( src_end ) )
2276
+ . try_fold :: < _ , _ , Result < _ , !> > ( sink, write_in_place_with_drop ( dst_end ) )
2272
2277
. unwrap ( ) ;
2273
2278
// iteration succeeded, don't drop head
2274
2279
let sink = mem:: ManuallyDrop :: new ( sink) ;
2275
2280
sink. dst
2276
2281
} else {
2277
- iterator. try_fold :: < _ , _ , Result < _ , !> > ( src_buf , write_in_place ( src_end ) ) . unwrap ( )
2282
+ iterator. try_fold :: < _ , _ , Result < _ , !> > ( dst_buf , write_in_place ( dst_end ) ) . unwrap ( )
2278
2283
} ;
2279
2284
2280
2285
let src = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
@@ -2289,8 +2294,8 @@ where
2289
2294
src. forget_in_place ( ) ;
2290
2295
2291
2296
let vec = unsafe {
2292
- let len = dst. offset_from ( src_buf ) as usize ;
2293
- Vec :: from_raw_parts ( src_buf , len, cap)
2297
+ let len = dst. offset_from ( dst_buf ) as usize ;
2298
+ Vec :: from_raw_parts ( dst_buf , len, cap)
2294
2299
} ;
2295
2300
2296
2301
vec
@@ -3010,12 +3015,15 @@ unsafe impl<T> SourceIter for IntoIter<T> {
3010
3015
}
3011
3016
3012
3017
// internal helper trait for in-place iteration specialization.
3013
- pub ( crate ) trait AsIntoIter < T > {
3014
- fn as_into_iter ( & mut self ) -> & mut IntoIter < T > ;
3018
+ pub ( crate ) trait AsIntoIter {
3019
+ type Item ;
3020
+ fn as_into_iter ( & mut self ) -> & mut IntoIter < Self :: Item > ;
3015
3021
}
3016
3022
3017
- impl < T > AsIntoIter < T > for IntoIter < T > {
3018
- fn as_into_iter ( & mut self ) -> & mut IntoIter < T > {
3023
+ impl < T > AsIntoIter for IntoIter < T > {
3024
+ type Item = T ;
3025
+
3026
+ fn as_into_iter ( & mut self ) -> & mut IntoIter < Self :: Item > {
3019
3027
self
3020
3028
}
3021
3029
}
0 commit comments