@@ -2240,23 +2240,28 @@ fn write_in_place_with_drop<T>(
22402240 }
22412241}
22422242
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
22462243impl < T , I > SpecFrom < T , I > for Vec < T >
22472244where
2248- I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter < T > > ,
2245+ I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter > ,
22492246{
22502247 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+ {
22542259 return SpecFromNested :: from_iter ( iterator) ;
22552260 }
22562261
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 )
22602265 } ;
22612266
22622267 // use try-fold
@@ -2266,15 +2271,15 @@ where
22662271 let dst = if mem:: needs_drop :: < T > ( ) {
22672272 // special-case drop handling since it forces us to lug that extra field around which
22682273 // can inhibit optimizations
2269- let sink = InPlaceDrop { inner : src_buf , dst : src_buf } ;
2274+ let sink = InPlaceDrop { inner : dst_buf , dst : dst_buf } ;
22702275 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 ) )
22722277 . unwrap ( ) ;
22732278 // iteration succeeded, don't drop head
22742279 let sink = mem:: ManuallyDrop :: new ( sink) ;
22752280 sink. dst
22762281 } 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 ( )
22782283 } ;
22792284
22802285 let src = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
@@ -2289,8 +2294,8 @@ where
22892294 src. forget_in_place ( ) ;
22902295
22912296 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)
22942299 } ;
22952300
22962301 vec
@@ -3010,12 +3015,15 @@ unsafe impl<T> SourceIter for IntoIter<T> {
30103015}
30113016
30123017// 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 > ;
30153021}
30163022
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 > {
30193027 self
30203028 }
30213029}
0 commit comments