@@ -2,6 +2,8 @@ use std::any::Any;
2
2
use std:: sync:: { Arc , Weak } ;
3
3
use std:: cell:: RefCell ;
4
4
use std:: cmp:: PartialEq ;
5
+ use std:: iter:: TrustedLen ;
6
+ use std:: mem;
5
7
6
8
#[ test]
7
9
fn uninhabited ( ) {
@@ -85,3 +87,120 @@ fn eq() {
85
87
assert ! ( !( x != x) ) ;
86
88
assert_eq ! ( * x. 0 . borrow( ) , 0 ) ;
87
89
}
90
+
91
+ type Rc < T > = Arc < T > ;
92
+
93
+ const SHARED_ITER_MAX : u16 = 100 ;
94
+
95
+ fn assert_trusted_len < I : TrustedLen > ( _: & I ) { }
96
+
97
+ #[ test]
98
+ fn shared_from_iter_normal ( ) {
99
+ // Exercise the base implementation for non-`TrustedLen` iterators.
100
+ {
101
+ // `Filter` is never `TrustedLen` since we don't
102
+ // know statically how many elements will be kept:
103
+ let iter = ( 0 ..SHARED_ITER_MAX ) . filter ( |x| x % 2 == 0 ) . map ( Box :: new) ;
104
+
105
+ // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
106
+ let vec = iter. clone ( ) . collect :: < Vec < _ > > ( ) ;
107
+ let rc = iter. collect :: < Rc < [ _ ] > > ( ) ;
108
+ assert_eq ! ( & * vec, & * rc) ;
109
+
110
+ // Clone a bit and let these get dropped.
111
+ {
112
+ let _rc_2 = rc. clone ( ) ;
113
+ let _rc_3 = rc. clone ( ) ;
114
+ let _rc_4 = Rc :: downgrade ( & _rc_3) ;
115
+ }
116
+ } // Drop what hasn't been here.
117
+ }
118
+
119
+ #[ test]
120
+ fn shared_from_iter_trustedlen_normal ( ) {
121
+ // Exercise the `TrustedLen` implementation under normal circumstances
122
+ // where `size_hint()` matches `(_, Some(exact_len))`.
123
+ {
124
+ let iter = ( 0 ..SHARED_ITER_MAX ) . map ( Box :: new) ;
125
+ assert_trusted_len ( & iter) ;
126
+
127
+ // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
128
+ let vec = iter. clone ( ) . collect :: < Vec < _ > > ( ) ;
129
+ let rc = iter. collect :: < Rc < [ _ ] > > ( ) ;
130
+ assert_eq ! ( & * vec, & * rc) ;
131
+ assert_eq ! ( mem:: size_of:: <Box <u16 >>( ) * SHARED_ITER_MAX as usize , mem:: size_of_val( & * rc) ) ;
132
+
133
+ // Clone a bit and let these get dropped.
134
+ {
135
+ let _rc_2 = rc. clone ( ) ;
136
+ let _rc_3 = rc. clone ( ) ;
137
+ let _rc_4 = Rc :: downgrade ( & _rc_3) ;
138
+ }
139
+ } // Drop what hasn't been here.
140
+
141
+ // Try a ZST to make sure it is handled well.
142
+ {
143
+ let iter = ( 0 ..SHARED_ITER_MAX ) . map ( |_| ( ) ) ;
144
+ let vec = iter. clone ( ) . collect :: < Vec < _ > > ( ) ;
145
+ let rc = iter. collect :: < Rc < [ _ ] > > ( ) ;
146
+ assert_eq ! ( & * vec, & * rc) ;
147
+ assert_eq ! ( 0 , mem:: size_of_val( & * rc) ) ;
148
+ {
149
+ let _rc_2 = rc. clone ( ) ;
150
+ let _rc_3 = rc. clone ( ) ;
151
+ let _rc_4 = Rc :: downgrade ( & _rc_3) ;
152
+ }
153
+ }
154
+ }
155
+
156
+ #[ test]
157
+ #[ should_panic = "I've almost got 99 problems." ]
158
+ fn shared_from_iter_trustedlen_panic ( ) {
159
+ // Exercise the `TrustedLen` implementation when `size_hint()` matches
160
+ // `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
161
+ let iter = ( 0 ..SHARED_ITER_MAX )
162
+ . map ( |val| {
163
+ match val {
164
+ 98 => panic ! ( "I've almost got 99 problems." ) ,
165
+ _ => Box :: new ( val) ,
166
+ }
167
+ } ) ;
168
+ assert_trusted_len ( & iter) ;
169
+ let _ = iter. collect :: < Rc < [ _ ] > > ( ) ;
170
+
171
+ panic ! ( "I am unreachable." ) ;
172
+ }
173
+
174
+ #[ test]
175
+ fn shared_from_iter_trustedlen_no_fuse ( ) {
176
+ // Exercise the `TrustedLen` implementation when `size_hint()` matches
177
+ // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner.
178
+ struct Iter ( std:: vec:: IntoIter < Option < Box < u8 > > > ) ;
179
+
180
+ unsafe impl TrustedLen for Iter { }
181
+
182
+ impl Iterator for Iter {
183
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
184
+ ( 2 , Some ( 2 ) )
185
+ }
186
+
187
+ type Item = Box < u8 > ;
188
+
189
+ fn next ( & mut self ) -> Option < Self :: Item > {
190
+ self . 0 . next ( ) . flatten ( )
191
+ }
192
+ }
193
+
194
+ let vec = vec ! [
195
+ Some ( Box :: new( 42 ) ) ,
196
+ Some ( Box :: new( 24 ) ) ,
197
+ None ,
198
+ Some ( Box :: new( 12 ) ) ,
199
+ ] ;
200
+ let iter = Iter ( vec. into_iter ( ) ) ;
201
+ assert_trusted_len ( & iter) ;
202
+ assert_eq ! (
203
+ & [ Box :: new( 42 ) , Box :: new( 24 ) ] ,
204
+ & * iter. collect:: <Rc <[ _] >>( )
205
+ ) ;
206
+ }
0 commit comments