]> git.lizzy.rs Git - rust.git/blob - tests/run-pass/rc.rs
rustup (and account for stabilization)
[rust.git] / tests / run-pass / rc.rs
1 #![feature(new_uninit)]
2 #![feature(get_mut_unchecked)]
3
4 use std::cell::{Cell, RefCell};
5 use std::rc::{Rc, Weak};
6 use std::sync::Arc;
7 use std::fmt::Debug;
8
9 fn rc_refcell() {
10     let r = Rc::new(RefCell::new(42));
11     let r2 = r.clone();
12     *r.borrow_mut() += 10;
13     let x = *r2.borrow();
14     assert_eq!(x, 52);
15 }
16
17 fn rc_cell() {
18     let r = Rc::new(Cell::new(42));
19     let r2 = r.clone();
20     let x = r.get();
21     r2.set(x + x);
22     assert_eq!(r.get(), 84);
23 }
24
25 fn rc_refcell2() {
26     let r = Rc::new(RefCell::new(42));
27     let r2 = r.clone();
28     *r.borrow_mut() += 10;
29     let x = r2.borrow();
30     let r3 = r.clone();
31     let y = r3.borrow();
32     assert_eq!((*x + *y)/2, 52);
33 }
34
35 fn rc_raw() {
36     let r = Rc::new(0);
37     let r2 = Rc::into_raw(r.clone());
38     let r2 = unsafe { Rc::from_raw(r2) };
39     assert!(Rc::ptr_eq(&r, &r2));
40     drop(r);
41     assert!(Rc::try_unwrap(r2).is_ok());
42 }
43
44 fn arc() {
45     fn test() -> Arc<i32> {
46         let a = Arc::new(42);
47         a
48     }
49     assert_eq!(*test(), 42);
50 }
51
52 // Make sure this Rc doesn't fall apart when touched
53 fn check_unique_rc<T: ?Sized>(mut r: Rc<T>) {
54     let r2 = r.clone();
55     assert!(Rc::get_mut(&mut r).is_none());
56     drop(r2);
57     assert!(Rc::get_mut(&mut r).is_some());
58 }
59
60 fn rc_from() {
61     check_unique_rc::<[_]>(Rc::from(&[1,2,3] as &[_]));
62     check_unique_rc::<[_]>(Rc::from(vec![1,2,3]));
63     check_unique_rc::<[_]>(Rc::from(Box::new([1,2,3]) as Box<[_]>));
64     check_unique_rc::<str>(Rc::from("Hello, World!"));
65 }
66
67 fn rc_fat_ptr_eq() {
68     let p = Rc::new(1) as Rc<dyn Debug>;
69     let a: *const dyn Debug = &*p;
70     let r = Rc::into_raw(p);
71     assert!(a == r);
72     drop(unsafe { Rc::from_raw(r) });
73 }
74
75 /// Taken from the `Weak::into_raw` doctest.
76 fn weak_into_raw() {
77     let strong = Rc::new(42);
78     let weak = Rc::downgrade(&strong);
79     let raw = Weak::into_raw(weak);
80
81     assert_eq!(1, Rc::weak_count(&strong));
82     assert_eq!(42, unsafe { *raw });
83
84     drop(unsafe { Weak::from_raw(raw) });
85     assert_eq!(0, Rc::weak_count(&strong));
86 }
87
88 /// Taken from the `Weak::from_raw` doctest.
89 fn weak_from_raw() {
90     let strong = Rc::new(42);
91
92     let raw_1 = Weak::into_raw(Rc::downgrade(&strong));
93     let raw_2 = Weak::into_raw(Rc::downgrade(&strong));
94
95     assert_eq!(2, Rc::weak_count(&strong));
96
97     assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
98     assert_eq!(1, Rc::weak_count(&strong));
99
100     drop(strong);
101
102     // Decrement the last weak count.
103     assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none());
104 }
105
106 fn rc_uninit() {
107     let mut five = Rc::<Box<u32>>::new_uninit();
108     let five = unsafe {
109         // Deferred initialization:
110         Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(Box::new(5));
111         five.assume_init()
112     };
113     assert_eq!(**five, 5)
114 }
115
116 fn rc_uninit_slice() {
117     let mut values = Rc::<[Box<usize>]>::new_uninit_slice(3);
118
119     let values = unsafe {
120         // Deferred initialization:
121         Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(Box::new(0));
122         Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(Box::new(1));
123         Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(Box::new(2));
124
125         values.assume_init()
126     };
127
128     for (idx, i) in values.iter().enumerate() {
129         assert_eq!(idx, **i);
130     }
131 }
132
133 fn main() {
134     rc_fat_ptr_eq();
135     rc_refcell();
136     rc_refcell2();
137     rc_cell();
138     rc_raw();
139     rc_from();
140     weak_into_raw();
141     weak_from_raw();
142     rc_uninit();
143     rc_uninit_slice();
144
145     arc();
146 }