]>
Commit | Line | Data |
---|---|---|
8faf50e0 | 1 | use std::any::Any; |
0731742a XL |
2 | use std::cell::RefCell; |
3 | use std::cmp::PartialEq; | |
416331ca XL |
4 | use std::iter::TrustedLen; |
5 | use std::mem; | |
d9bb1a4e | 6 | use std::sync::{Arc, Weak}; |
8faf50e0 XL |
7 | |
8 | #[test] | |
9 | fn uninhabited() { | |
10 | enum Void {} | |
11 | let mut a = Weak::<Void>::new(); | |
12 | a = a.clone(); | |
13 | assert!(a.upgrade().is_none()); | |
14 | ||
d9bb1a4e | 15 | let mut a: Weak<dyn Any> = a; // Unsizing |
8faf50e0 XL |
16 | a = a.clone(); |
17 | assert!(a.upgrade().is_none()); | |
18 | } | |
19 | ||
20 | #[test] | |
21 | fn slice() { | |
22 | let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]); | |
d9bb1a4e FG |
23 | let a: Arc<[u32]> = a; // Unsizing |
24 | let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]); // Conversion | |
8faf50e0 XL |
25 | assert_eq!(a, b); |
26 | ||
27 | // Exercise is_dangling() with a DST | |
28 | let mut a = Arc::downgrade(&a); | |
29 | a = a.clone(); | |
30 | assert!(a.upgrade().is_some()); | |
31 | } | |
32 | ||
33 | #[test] | |
34 | fn trait_object() { | |
35 | let a: Arc<u32> = Arc::new(4); | |
d9bb1a4e | 36 | let a: Arc<dyn Any> = a; // Unsizing |
8faf50e0 XL |
37 | |
38 | // Exercise is_dangling() with a DST | |
39 | let mut a = Arc::downgrade(&a); | |
40 | a = a.clone(); | |
41 | assert!(a.upgrade().is_some()); | |
42 | ||
43 | let mut b = Weak::<u32>::new(); | |
44 | b = b.clone(); | |
45 | assert!(b.upgrade().is_none()); | |
d9bb1a4e | 46 | let mut b: Weak<dyn Any> = b; // Unsizing |
8faf50e0 XL |
47 | b = b.clone(); |
48 | assert!(b.upgrade().is_none()); | |
49 | } | |
0731742a XL |
50 | |
51 | #[test] | |
52 | fn float_nan_ne() { | |
53 | let x = Arc::new(std::f32::NAN); | |
54 | assert!(x != x); | |
55 | assert!(!(x == x)); | |
56 | } | |
57 | ||
58 | #[test] | |
59 | fn partial_eq() { | |
d9bb1a4e | 60 | struct TestPEq(RefCell<usize>); |
0731742a XL |
61 | impl PartialEq for TestPEq { |
62 | fn eq(&self, other: &TestPEq) -> bool { | |
63 | *self.0.borrow_mut() += 1; | |
64 | *other.0.borrow_mut() += 1; | |
65 | true | |
66 | } | |
67 | } | |
68 | let x = Arc::new(TestPEq(RefCell::new(0))); | |
69 | assert!(x == x); | |
70 | assert!(!(x != x)); | |
71 | assert_eq!(*x.0.borrow(), 4); | |
72 | } | |
73 | ||
74 | #[test] | |
75 | fn eq() { | |
76 | #[derive(Eq)] | |
d9bb1a4e | 77 | struct TestEq(RefCell<usize>); |
0731742a XL |
78 | impl PartialEq for TestEq { |
79 | fn eq(&self, other: &TestEq) -> bool { | |
80 | *self.0.borrow_mut() += 1; | |
81 | *other.0.borrow_mut() += 1; | |
82 | true | |
83 | } | |
84 | } | |
85 | let x = Arc::new(TestEq(RefCell::new(0))); | |
86 | assert!(x == x); | |
87 | assert!(!(x != x)); | |
88 | assert_eq!(*x.0.borrow(), 0); | |
89 | } | |
416331ca XL |
90 | |
91 | // The test code below is identical to that in `rc.rs`. | |
92 | // For better maintainability we therefore define this type alias. | |
93 | type Rc<T> = Arc<T>; | |
94 | ||
95 | const SHARED_ITER_MAX: u16 = 100; | |
96 | ||
97 | fn assert_trusted_len<I: TrustedLen>(_: &I) {} | |
98 | ||
99 | #[test] | |
100 | fn shared_from_iter_normal() { | |
101 | // Exercise the base implementation for non-`TrustedLen` iterators. | |
102 | { | |
103 | // `Filter` is never `TrustedLen` since we don't | |
104 | // know statically how many elements will be kept: | |
105 | let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new); | |
106 | ||
107 | // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference: | |
108 | let vec = iter.clone().collect::<Vec<_>>(); | |
109 | let rc = iter.collect::<Rc<[_]>>(); | |
110 | assert_eq!(&*vec, &*rc); | |
111 | ||
112 | // Clone a bit and let these get dropped. | |
113 | { | |
114 | let _rc_2 = rc.clone(); | |
115 | let _rc_3 = rc.clone(); | |
116 | let _rc_4 = Rc::downgrade(&_rc_3); | |
117 | } | |
118 | } // Drop what hasn't been here. | |
119 | } | |
120 | ||
121 | #[test] | |
122 | fn shared_from_iter_trustedlen_normal() { | |
123 | // Exercise the `TrustedLen` implementation under normal circumstances | |
124 | // where `size_hint()` matches `(_, Some(exact_len))`. | |
125 | { | |
126 | let iter = (0..SHARED_ITER_MAX).map(Box::new); | |
127 | assert_trusted_len(&iter); | |
128 | ||
129 | // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference: | |
130 | let vec = iter.clone().collect::<Vec<_>>(); | |
131 | let rc = iter.collect::<Rc<[_]>>(); | |
132 | assert_eq!(&*vec, &*rc); | |
133 | assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc)); | |
134 | ||
135 | // Clone a bit and let these get dropped. | |
136 | { | |
137 | let _rc_2 = rc.clone(); | |
138 | let _rc_3 = rc.clone(); | |
139 | let _rc_4 = Rc::downgrade(&_rc_3); | |
140 | } | |
141 | } // Drop what hasn't been here. | |
142 | ||
143 | // Try a ZST to make sure it is handled well. | |
144 | { | |
46de9a89 | 145 | let iter = (0..SHARED_ITER_MAX).map(drop); |
416331ca XL |
146 | let vec = iter.clone().collect::<Vec<_>>(); |
147 | let rc = iter.collect::<Rc<[_]>>(); | |
148 | assert_eq!(&*vec, &*rc); | |
149 | assert_eq!(0, mem::size_of_val(&*rc)); | |
150 | { | |
151 | let _rc_2 = rc.clone(); | |
152 | let _rc_3 = rc.clone(); | |
153 | let _rc_4 = Rc::downgrade(&_rc_3); | |
154 | } | |
155 | } | |
156 | } | |
157 | ||
158 | #[test] | |
159 | #[should_panic = "I've almost got 99 problems."] | |
160 | fn shared_from_iter_trustedlen_panic() { | |
161 | // Exercise the `TrustedLen` implementation when `size_hint()` matches | |
162 | // `(_, Some(exact_len))` but where `.next()` drops before the last iteration. | |
d9bb1a4e FG |
163 | let iter = (0..SHARED_ITER_MAX).map(|val| match val { |
164 | 98 => panic!("I've almost got 99 problems."), | |
165 | _ => Box::new(val), | |
166 | }); | |
416331ca XL |
167 | assert_trusted_len(&iter); |
168 | let _ = iter.collect::<Rc<[_]>>(); | |
169 | ||
170 | panic!("I am unreachable."); | |
171 | } | |
172 | ||
173 | #[test] | |
174 | fn shared_from_iter_trustedlen_no_fuse() { | |
175 | // Exercise the `TrustedLen` implementation when `size_hint()` matches | |
176 | // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner. | |
177 | struct Iter(std::vec::IntoIter<Option<Box<u8>>>); | |
178 | ||
179 | unsafe impl TrustedLen for Iter {} | |
180 | ||
181 | impl Iterator for Iter { | |
182 | fn size_hint(&self) -> (usize, Option<usize>) { | |
183 | (2, Some(2)) | |
184 | } | |
185 | ||
186 | type Item = Box<u8>; | |
187 | ||
188 | fn next(&mut self) -> Option<Self::Item> { | |
189 | self.0.next().flatten() | |
190 | } | |
191 | } | |
192 | ||
d9bb1a4e | 193 | let vec = vec![Some(Box::new(42)), Some(Box::new(24)), None, Some(Box::new(12))]; |
416331ca XL |
194 | let iter = Iter(vec.into_iter()); |
195 | assert_trusted_len(&iter); | |
d9bb1a4e | 196 | assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>()); |
416331ca | 197 | } |