@@ -2135,23 +2135,28 @@ fn write_in_place_with_drop<T>(
2135
2135
}
2136
2136
}
2137
2137
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
2141
2138
impl < T , I > SpecFrom < T , I > for Vec < T >
2142
2139
where
2143
- I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter < T > > ,
2140
+ I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source : AsIntoIter > ,
2144
2141
{
2145
2142
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
+ {
2149
2154
return SpecFromNested :: from_iter ( iterator) ;
2150
2155
}
2151
2156
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 )
2155
2160
} ;
2156
2161
2157
2162
// use try-fold
@@ -2161,15 +2166,15 @@ where
2161
2166
let dst = if mem:: needs_drop :: < T > ( ) {
2162
2167
// special-case drop handling since it forces us to lug that extra field around which
2163
2168
// can inhibit optimizations
2164
- let sink = InPlaceDrop { inner : src_buf , dst : src_buf } ;
2169
+ let sink = InPlaceDrop { inner : dst_buf , dst : dst_buf } ;
2165
2170
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 ) )
2167
2172
. unwrap ( ) ;
2168
2173
// iteration succeeded, don't drop head
2169
2174
let sink = mem:: ManuallyDrop :: new ( sink) ;
2170
2175
sink. dst
2171
2176
} 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 ( )
2173
2178
} ;
2174
2179
2175
2180
let src = unsafe { iterator. as_inner ( ) . as_into_iter ( ) } ;
@@ -2184,8 +2189,8 @@ where
2184
2189
src. forget_in_place ( ) ;
2185
2190
2186
2191
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)
2189
2194
} ;
2190
2195
2191
2196
vec
@@ -2856,12 +2861,15 @@ unsafe impl<T> SourceIter for IntoIter<T> {
2856
2861
}
2857
2862
2858
2863
// 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 > ;
2861
2867
}
2862
2868
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 > {
2865
2873
self
2866
2874
}
2867
2875
}
0 commit comments