@@ -2135,23 +2135,28 @@ fn write_in_place_with_drop<T>(
21352135 }
21362136}
21372137
2138- // Further specialization potential once
2139- // https://github.com/rust-lang/rust/issues/62645 has been solved:
2140- // T can be split into IN and OUT which only need to have the same size and alignment
21412138impl < T , I > SpecFrom < T , I > for Vec < T >
21422139where
2143- I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter < T > > ,
2140+ I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter > ,
21442141{
21452142 default fn from_iter ( mut iterator : I ) -> Self {
2146- // This specialization only makes sense if we're juggling real allocations.
2147- // Additionally some of the pointer arithmetic would panic on ZSTs.
2148- if mem:: size_of :: < T > ( ) == 0 {
2143+ // Additional requirements which cannot expressed via trait bounds. We rely on const eval
2144+ // instead:
2145+ // a) no ZSTs as there would be no allocation to reuse and pointer arithmetic would panic
2146+ // b) size match as required by Alloc contract
2147+ // c) alignments match as required by Alloc contract
2148+ if mem:: size_of :: < T > ( ) == 0
2149+ || mem:: size_of :: < T > ( )
2150+ != mem:: size_of :: < <<I as SourceIter >:: Source as AsIntoIter >:: Item > ( )
2151+ || mem:: align_of :: < T > ( )
2152+ != mem:: align_of :: < <<I as SourceIter >:: Source as AsIntoIter >:: Item > ( )
2153+ {
21492154 return SpecFromNested :: from_iter ( iterator) ;
21502155 }
21512156
2152- let ( src_buf, src_end , cap) = {
2153- let inner = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
2154- ( inner. buf . as_ptr ( ) , inner. end , inner. cap )
2157+ let ( src_buf, dst_buf , dst_end , cap) = unsafe {
2158+ let inner = iterator. as_inner ( ) . as_into_iter ( ) ;
2159+ ( inner. buf . as_ptr ( ) , inner. buf . as_ptr ( ) as * mut T , inner . end as * const T , inner. cap )
21552160 } ;
21562161
21572162 // use try-fold
@@ -2161,15 +2166,15 @@ where
21612166 let dst = if mem:: needs_drop :: < T > ( ) {
21622167 // special-case drop handling since it forces us to lug that extra field around which
21632168 // can inhibit optimizations
2164- let sink = InPlaceDrop { inner : src_buf , dst : src_buf } ;
2169+ let sink = InPlaceDrop { inner : dst_buf , dst : dst_buf } ;
21652170 let sink = iterator
2166- . try_fold :: < _ , _ , Result < _ , !> > ( sink, write_in_place_with_drop ( src_end ) )
2171+ . try_fold :: < _ , _ , Result < _ , !> > ( sink, write_in_place_with_drop ( dst_end ) )
21672172 . unwrap ( ) ;
21682173 // iteration succeeded, don't drop head
21692174 let sink = mem:: ManuallyDrop :: new ( sink) ;
21702175 sink. dst
21712176 } else {
2172- iterator. try_fold :: < _ , _ , Result < _ , !> > ( src_buf , write_in_place ( src_end ) ) . unwrap ( )
2177+ iterator. try_fold :: < _ , _ , Result < _ , !> > ( dst_buf , write_in_place ( dst_end ) ) . unwrap ( )
21732178 } ;
21742179
21752180 let src = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
@@ -2184,8 +2189,8 @@ where
21842189 src. forget_in_place ( ) ;
21852190
21862191 let vec = unsafe {
2187- let len = dst. offset_from ( src_buf ) as usize ;
2188- Vec :: from_raw_parts ( src_buf , len, cap)
2192+ let len = dst. offset_from ( dst_buf ) as usize ;
2193+ Vec :: from_raw_parts ( dst_buf , len, cap)
21892194 } ;
21902195
21912196 vec
@@ -2856,12 +2861,15 @@ unsafe impl<T> SourceIter for IntoIter<T> {
28562861}
28572862
28582863// internal helper trait for in-place iteration specialization.
2859- pub ( crate ) trait AsIntoIter < T > {
2860- fn as_into_iter ( & mut self ) -> & mut IntoIter < T > ;
2864+ pub ( crate ) trait AsIntoIter {
2865+ type Item ;
2866+ fn as_into_iter ( & mut self ) -> & mut IntoIter < Self :: Item > ;
28612867}
28622868
2863- impl < T > AsIntoIter < T > for IntoIter < T > {
2864- fn as_into_iter ( & mut self ) -> & mut IntoIter < T > {
2869+ impl < T > AsIntoIter for IntoIter < T > {
2870+ type Item = T ;
2871+
2872+ fn as_into_iter ( & mut self ) -> & mut IntoIter < Self :: Item > {
28652873 self
28662874 }
28672875}
0 commit comments