@@ -2082,83 +2082,6 @@ impl<T> Drop for InPlaceDrop<T> {
2082
2082
}
2083
2083
}
2084
2084
2085
- fn from_into_iter_source < T , I > ( mut iterator : I ) -> Vec < T >
2086
- where
2087
- I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source = IntoIter < T > > ,
2088
- {
2089
- // This specialization only makes sense if we're juggling real allocations.
2090
- // Additionally some of the pointer arithmetic would panic on ZSTs.
2091
- if mem:: size_of :: < T > ( ) == 0 {
2092
- return SpecFromNested :: from_iter ( iterator) ;
2093
- }
2094
-
2095
- let src_buf = iterator. as_inner ( ) . buf . as_ptr ( ) ;
2096
- let src_end = iterator. as_inner ( ) . end ;
2097
- let dst = src_buf;
2098
-
2099
- let dst = if mem:: needs_drop :: < T > ( ) {
2100
- // special-case drop handling since it prevents vectorization
2101
- let mut sink = InPlaceDrop { inner : src_buf, dst, did_panic : true } ;
2102
- let _ = iterator. try_for_each :: < _ , Result < _ , !> > ( |item| {
2103
- unsafe {
2104
- debug_assert ! (
2105
- sink. dst as * const _ <= src_end,
2106
- "InPlaceIterable contract violation"
2107
- ) ;
2108
- ptr:: write ( sink. dst , item) ;
2109
- sink. dst = sink. dst . add ( 1 ) ;
2110
- }
2111
- Ok ( ( ) )
2112
- } ) ;
2113
- sink. did_panic = false ;
2114
- sink. dst
2115
- } else {
2116
- // use try-fold
2117
- // - it vectorizes better
2118
- // - unlike most internal iteration methods methods it only takes a &mut self
2119
- // - lets us thread the write pointer through its innards and get it back in the end
2120
- iterator
2121
- . try_fold :: < _ , _ , Result < _ , !> > ( dst, move |mut dst, item| {
2122
- unsafe {
2123
- // the InPlaceIterable contract cannot be verified precisely here since
2124
- // try_fold has an exclusive reference to the source pointer
2125
- // all we can do is check if it's still in range
2126
- debug_assert ! ( dst as * const _ <= src_end, "InPlaceIterable contract violation" ) ;
2127
- ptr:: write ( dst, item) ;
2128
- dst = dst. add ( 1 ) ;
2129
- }
2130
- Ok ( dst)
2131
- } )
2132
- . unwrap ( )
2133
- } ;
2134
-
2135
- let src = iterator. as_inner ( ) ;
2136
- // check if SourceIter and InPlaceIterable contracts were upheld.
2137
- // caveat: if they weren't we may not even make it to this point
2138
- debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
2139
- debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
2140
-
2141
- if mem:: needs_drop :: < T > ( ) {
2142
- // drop tail if iterator was only partially exhaused
2143
- unsafe {
2144
- ptr:: drop_in_place ( src. as_mut_slice ( ) ) ;
2145
- }
2146
- }
2147
-
2148
- let vec = unsafe {
2149
- let len = dst. offset_from ( src_buf) as usize ;
2150
- Vec :: from_raw_parts ( src. buf . as_ptr ( ) , len, src. cap )
2151
- } ;
2152
- // prevent drop of the underlying storage by turning the IntoIter into
2153
- // the equivalent of Vec::new().into_iter()
2154
- src. cap = 0 ;
2155
- src. buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2156
- src. ptr = src. buf . as_ptr ( ) ;
2157
- src. end = src. buf . as_ptr ( ) ;
2158
-
2159
- vec
2160
- }
2161
-
2162
2085
impl < T > SpecFrom < T , IntoIter < T > > for Vec < T > {
2163
2086
fn from_iter ( iterator : IntoIter < T > ) -> Self {
2164
2087
// A common case is passing a vector into a function which immediately
@@ -2193,8 +2116,81 @@ impl<T, I> SpecFrom<T, I> for Vec<T>
2193
2116
where
2194
2117
I : Iterator < Item = T > + InPlaceIterable + SourceIter < Source = IntoIter < T > > ,
2195
2118
{
2196
- default fn from_iter ( iterator : I ) -> Self {
2197
- from_into_iter_source ( iterator)
2119
+ default fn from_iter ( mut iterator : I ) -> Self {
2120
+ // This specialization only makes sense if we're juggling real allocations.
2121
+ // Additionally some of the pointer arithmetic would panic on ZSTs.
2122
+ if mem:: size_of :: < T > ( ) == 0 {
2123
+ return SpecFromNested :: from_iter ( iterator) ;
2124
+ }
2125
+
2126
+ let src_buf = iterator. as_inner ( ) . buf . as_ptr ( ) ;
2127
+ let src_end = iterator. as_inner ( ) . end ;
2128
+ let dst = src_buf;
2129
+
2130
+ let dst = if mem:: needs_drop :: < T > ( ) {
2131
+ // special-case drop handling since it prevents vectorization
2132
+ let mut sink = InPlaceDrop { inner : src_buf, dst, did_panic : true } ;
2133
+ let _ = iterator. try_for_each :: < _ , Result < _ , !> > ( |item| {
2134
+ unsafe {
2135
+ debug_assert ! (
2136
+ sink. dst as * const _ <= src_end,
2137
+ "InPlaceIterable contract violation"
2138
+ ) ;
2139
+ ptr:: write ( sink. dst , item) ;
2140
+ sink. dst = sink. dst . add ( 1 ) ;
2141
+ }
2142
+ Ok ( ( ) )
2143
+ } ) ;
2144
+ sink. did_panic = false ;
2145
+ sink. dst
2146
+ } else {
2147
+ // use try-fold
2148
+ // - it vectorizes better
2149
+ // - unlike most internal iteration methods methods it only takes a &mut self
2150
+ // - lets us thread the write pointer through its innards and get it back in the end
2151
+ iterator
2152
+ . try_fold :: < _ , _ , Result < _ , !> > ( dst, move |mut dst, item| {
2153
+ unsafe {
2154
+ // the InPlaceIterable contract cannot be verified precisely here since
2155
+ // try_fold has an exclusive reference to the source pointer
2156
+ // all we can do is check if it's still in range
2157
+ debug_assert ! (
2158
+ dst as * const _ <= src_end,
2159
+ "InPlaceIterable contract violation"
2160
+ ) ;
2161
+ ptr:: write ( dst, item) ;
2162
+ dst = dst. add ( 1 ) ;
2163
+ }
2164
+ Ok ( dst)
2165
+ } )
2166
+ . unwrap ( )
2167
+ } ;
2168
+
2169
+ let src = iterator. as_inner ( ) ;
2170
+ // check if SourceIter and InPlaceIterable contracts were upheld.
2171
+ // caveat: if they weren't we may not even make it to this point
2172
+ debug_assert_eq ! ( src_buf, src. buf. as_ptr( ) ) ;
2173
+ debug_assert ! ( dst as * const _ <= src. ptr, "InPlaceIterable contract violation" ) ;
2174
+
2175
+ if mem:: needs_drop :: < T > ( ) {
2176
+ // drop tail if iterator was only partially exhaused
2177
+ unsafe {
2178
+ ptr:: drop_in_place ( src. as_mut_slice ( ) ) ;
2179
+ }
2180
+ }
2181
+
2182
+ let vec = unsafe {
2183
+ let len = dst. offset_from ( src_buf) as usize ;
2184
+ Vec :: from_raw_parts ( src. buf . as_ptr ( ) , len, src. cap )
2185
+ } ;
2186
+ // prevent drop of the underlying storage by turning the IntoIter into
2187
+ // the equivalent of Vec::new().into_iter()
2188
+ src. cap = 0 ;
2189
+ src. buf = unsafe { NonNull :: new_unchecked ( RawVec :: NEW . ptr ( ) ) } ;
2190
+ src. ptr = src. buf . as_ptr ( ) ;
2191
+ src. end = src. buf . as_ptr ( ) ;
2192
+
2193
+ vec
2198
2194
}
2199
2195
}
2200
2196
0 commit comments