]> git.lizzy.rs Git - rust.git/blob - library/alloc/tests/rc.rs
rustdoc: remove unused JS IIFE from main.js
[rust.git] / library / alloc / tests / rc.rs
1 use std::any::Any;
2 use std::cell::RefCell;
3 use std::cmp::PartialEq;
4 use std::iter::TrustedLen;
5 use std::mem;
6 use std::rc::{Rc, Weak};
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
15     let mut a: Weak<dyn Any> = a; // Unsizing
16     a = a.clone();
17     assert!(a.upgrade().is_none());
18 }
19
20 #[test]
21 fn slice() {
22     let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
23     let a: Rc<[u32]> = a; // Unsizing
24     let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]); // Conversion
25     assert_eq!(a, b);
26
27     // Exercise is_dangling() with a DST
28     let mut a = Rc::downgrade(&a);
29     a = a.clone();
30     assert!(a.upgrade().is_some());
31 }
32
33 #[test]
34 fn trait_object() {
35     let a: Rc<u32> = Rc::new(4);
36     let a: Rc<dyn Any> = a; // Unsizing
37
38     // Exercise is_dangling() with a DST
39     let mut a = Rc::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());
46     let mut b: Weak<dyn Any> = b; // Unsizing
47     b = b.clone();
48     assert!(b.upgrade().is_none());
49 }
50
51 #[test]
52 fn float_nan_ne() {
53     let x = Rc::new(f32::NAN);
54     assert!(x != x);
55     assert!(!(x == x));
56 }
57
58 #[test]
59 fn partial_eq() {
60     struct TestPEq(RefCell<usize>);
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 = Rc::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)]
77     struct TestEq(RefCell<usize>);
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 = Rc::new(TestEq(RefCell::new(0)));
86     assert!(x == x);
87     assert!(!(x != x));
88     assert_eq!(*x.0.borrow(), 0);
89 }
90
91 const SHARED_ITER_MAX: u16 = 100;
92
93 fn assert_trusted_len<I: TrustedLen>(_: &I) {}
94
95 #[test]
96 fn shared_from_iter_normal() {
97     // Exercise the base implementation for non-`TrustedLen` iterators.
98     {
99         // `Filter` is never `TrustedLen` since we don't
100         // know statically how many elements will be kept:
101         let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new);
102
103         // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
104         let vec = iter.clone().collect::<Vec<_>>();
105         let rc = iter.collect::<Rc<[_]>>();
106         assert_eq!(&*vec, &*rc);
107
108         // Clone a bit and let these get dropped.
109         {
110             let _rc_2 = rc.clone();
111             let _rc_3 = rc.clone();
112             let _rc_4 = Rc::downgrade(&_rc_3);
113         }
114     } // Drop what hasn't been here.
115 }
116
117 #[test]
118 fn shared_from_iter_trustedlen_normal() {
119     // Exercise the `TrustedLen` implementation under normal circumstances
120     // where `size_hint()` matches `(_, Some(exact_len))`.
121     {
122         let iter = (0..SHARED_ITER_MAX).map(Box::new);
123         assert_trusted_len(&iter);
124
125         // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
126         let vec = iter.clone().collect::<Vec<_>>();
127         let rc = iter.collect::<Rc<[_]>>();
128         assert_eq!(&*vec, &*rc);
129         assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
130
131         // Clone a bit and let these get dropped.
132         {
133             let _rc_2 = rc.clone();
134             let _rc_3 = rc.clone();
135             let _rc_4 = Rc::downgrade(&_rc_3);
136         }
137     } // Drop what hasn't been here.
138
139     // Try a ZST to make sure it is handled well.
140     {
141         let iter = (0..SHARED_ITER_MAX).map(drop);
142         let vec = iter.clone().collect::<Vec<_>>();
143         let rc = iter.collect::<Rc<[_]>>();
144         assert_eq!(&*vec, &*rc);
145         assert_eq!(0, mem::size_of_val(&*rc));
146         {
147             let _rc_2 = rc.clone();
148             let _rc_3 = rc.clone();
149             let _rc_4 = Rc::downgrade(&_rc_3);
150         }
151     }
152 }
153
154 #[test]
155 #[should_panic = "I've almost got 99 problems."]
156 fn shared_from_iter_trustedlen_panic() {
157     // Exercise the `TrustedLen` implementation when `size_hint()` matches
158     // `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
159     let iter = (0..SHARED_ITER_MAX).map(|val| match val {
160         98 => panic!("I've almost got 99 problems."),
161         _ => Box::new(val),
162     });
163     assert_trusted_len(&iter);
164     let _ = iter.collect::<Rc<[_]>>();
165
166     panic!("I am unreachable.");
167 }
168
169 #[test]
170 fn shared_from_iter_trustedlen_no_fuse() {
171     // Exercise the `TrustedLen` implementation when `size_hint()` matches
172     // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner.
173     struct Iter(std::vec::IntoIter<Option<Box<u8>>>);
174
175     unsafe impl TrustedLen for Iter {}
176
177     impl Iterator for Iter {
178         fn size_hint(&self) -> (usize, Option<usize>) {
179             (2, Some(2))
180         }
181
182         type Item = Box<u8>;
183
184         fn next(&mut self) -> Option<Self::Item> {
185             self.0.next().flatten()
186         }
187     }
188
189     let vec = vec![Some(Box::new(42)), Some(Box::new(24)), None, Some(Box::new(12))];
190     let iter = Iter(vec.into_iter());
191     assert_trusted_len(&iter);
192     assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>());
193 }
194
195 #[test]
196 fn weak_may_dangle() {
197     fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> {
198         val.clone()
199     }
200
201     // Without #[may_dangle] we get:
202     let mut val = Weak::new();
203     hmm(&mut val);
204     //  ~~~~~~~~ borrowed value does not live long enough
205     //
206     // `val` dropped here while still borrowed
207     // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::rc::Weak`
208 }
209
210 #[test]
211 fn rc_from_vec_opt() {
212     let mut v = Vec::with_capacity(64);
213     v.push(0usize);
214     let addr = v.as_ptr().cast::<u8>();
215     let rc: Rc<[_]> = v.into();
216     unsafe {
217         assert_eq!(
218             rc.as_ptr().cast::<u8>().offset_from(addr),
219             (std::mem::size_of::<usize>() * 2) as isize,
220             "Vector allocation not reused"
221         );
222     }
223 }