]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | use core::cell::*; | |
12 | use core::default::Default; | |
13 | use std::mem::drop; | |
14 | ||
15 | #[test] | |
16 | fn smoketest_cell() { | |
85aaf69f | 17 | let x = Cell::new(10); |
1a4d82fc JJ |
18 | assert!(x == Cell::new(10)); |
19 | assert!(x.get() == 10); | |
20 | x.set(20); | |
21 | assert!(x == Cell::new(20)); | |
22 | assert!(x.get() == 20); | |
23 | ||
85aaf69f | 24 | let y = Cell::new((30, 40)); |
1a4d82fc JJ |
25 | assert!(y == Cell::new((30, 40))); |
26 | assert!(y.get() == (30, 40)); | |
27 | } | |
28 | ||
29 | #[test] | |
30 | fn cell_has_sensible_show() { | |
31 | let x = Cell::new("foo bar"); | |
32 | assert!(format!("{:?}", x).contains(x.get())); | |
33 | ||
34 | x.set("baz qux"); | |
35 | assert!(format!("{:?}", x).contains(x.get())); | |
36 | } | |
37 | ||
38 | #[test] | |
39 | fn ref_and_refmut_have_sensible_show() { | |
40 | let refcell = RefCell::new("foo"); | |
41 | ||
42 | let refcell_refmut = refcell.borrow_mut(); | |
43 | assert!(format!("{:?}", refcell_refmut).contains("foo")); | |
44 | drop(refcell_refmut); | |
45 | ||
46 | let refcell_ref = refcell.borrow(); | |
47 | assert!(format!("{:?}", refcell_ref).contains("foo")); | |
48 | drop(refcell_ref); | |
49 | } | |
50 | ||
51 | #[test] | |
52 | fn double_imm_borrow() { | |
85aaf69f | 53 | let x = RefCell::new(0); |
1a4d82fc JJ |
54 | let _b1 = x.borrow(); |
55 | x.borrow(); | |
56 | } | |
57 | ||
58 | #[test] | |
59 | fn no_mut_then_imm_borrow() { | |
85aaf69f | 60 | let x = RefCell::new(0); |
1a4d82fc | 61 | let _b1 = x.borrow_mut(); |
85aaf69f | 62 | assert_eq!(x.borrow_state(), BorrowState::Writing); |
1a4d82fc JJ |
63 | } |
64 | ||
65 | #[test] | |
66 | fn no_imm_then_borrow_mut() { | |
85aaf69f | 67 | let x = RefCell::new(0); |
1a4d82fc | 68 | let _b1 = x.borrow(); |
85aaf69f | 69 | assert_eq!(x.borrow_state(), BorrowState::Reading); |
1a4d82fc JJ |
70 | } |
71 | ||
72 | #[test] | |
73 | fn no_double_borrow_mut() { | |
85aaf69f SL |
74 | let x = RefCell::new(0); |
75 | assert_eq!(x.borrow_state(), BorrowState::Unused); | |
1a4d82fc | 76 | let _b1 = x.borrow_mut(); |
85aaf69f | 77 | assert_eq!(x.borrow_state(), BorrowState::Writing); |
1a4d82fc JJ |
78 | } |
79 | ||
80 | #[test] | |
81 | fn imm_release_borrow_mut() { | |
85aaf69f | 82 | let x = RefCell::new(0); |
1a4d82fc JJ |
83 | { |
84 | let _b1 = x.borrow(); | |
85 | } | |
86 | x.borrow_mut(); | |
87 | } | |
88 | ||
89 | #[test] | |
90 | fn mut_release_borrow_mut() { | |
85aaf69f | 91 | let x = RefCell::new(0); |
1a4d82fc JJ |
92 | { |
93 | let _b1 = x.borrow_mut(); | |
94 | } | |
95 | x.borrow(); | |
96 | } | |
97 | ||
98 | #[test] | |
99 | fn double_borrow_single_release_no_borrow_mut() { | |
85aaf69f | 100 | let x = RefCell::new(0); |
1a4d82fc JJ |
101 | let _b1 = x.borrow(); |
102 | { | |
103 | let _b2 = x.borrow(); | |
104 | } | |
c34b1796 | 105 | assert_eq!(x.borrow_state(), BorrowState::Reading); |
1a4d82fc JJ |
106 | } |
107 | ||
108 | #[test] | |
c34b1796 | 109 | #[should_panic] |
1a4d82fc | 110 | fn discard_doesnt_unborrow() { |
85aaf69f | 111 | let x = RefCell::new(0); |
1a4d82fc JJ |
112 | let _b = x.borrow(); |
113 | let _ = _b; | |
114 | let _b = x.borrow_mut(); | |
115 | } | |
116 | ||
117 | #[test] | |
62682a34 | 118 | fn ref_clone_updates_flag() { |
85aaf69f | 119 | let x = RefCell::new(0); |
1a4d82fc JJ |
120 | { |
121 | let b1 = x.borrow(); | |
c34b1796 | 122 | assert_eq!(x.borrow_state(), BorrowState::Reading); |
1a4d82fc | 123 | { |
62682a34 | 124 | let _b2 = Ref::clone(&b1); |
c34b1796 | 125 | assert_eq!(x.borrow_state(), BorrowState::Reading); |
1a4d82fc | 126 | } |
c34b1796 | 127 | assert_eq!(x.borrow_state(), BorrowState::Reading); |
1a4d82fc | 128 | } |
c34b1796 | 129 | assert_eq!(x.borrow_state(), BorrowState::Unused); |
1a4d82fc JJ |
130 | } |
131 | ||
62682a34 SL |
132 | #[test] |
133 | fn ref_map_does_not_update_flag() { | |
134 | let x = RefCell::new(Some(5)); | |
135 | { | |
136 | let b1: Ref<Option<u32>> = x.borrow(); | |
137 | assert_eq!(x.borrow_state(), BorrowState::Reading); | |
138 | { | |
139 | let b2: Ref<u32> = Ref::map(b1, |o| o.as_ref().unwrap()); | |
140 | assert_eq!(*b2, 5); | |
141 | assert_eq!(x.borrow_state(), BorrowState::Reading); | |
142 | } | |
143 | assert_eq!(x.borrow_state(), BorrowState::Unused); | |
144 | } | |
145 | assert_eq!(x.borrow_state(), BorrowState::Unused); | |
146 | } | |
147 | ||
148 | #[test] | |
149 | fn ref_map_accessor() { | |
150 | struct X(RefCell<(u32, char)>); | |
151 | impl X { | |
152 | fn accessor(&self) -> Ref<u32> { | |
153 | Ref::map(self.0.borrow(), |tuple| &tuple.0) | |
154 | } | |
155 | } | |
156 | let x = X(RefCell::new((7, 'z'))); | |
157 | let d: Ref<u32> = x.accessor(); | |
158 | assert_eq!(*d, 7); | |
159 | } | |
160 | ||
161 | #[test] | |
7453a54e | 162 | #[allow(deprecated)] |
62682a34 SL |
163 | fn ref_filter_map_accessor() { |
164 | struct X(RefCell<Result<u32, ()>>); | |
165 | impl X { | |
166 | fn accessor(&self) -> Option<Ref<u32>> { | |
167 | Ref::filter_map(self.0.borrow(), |r| r.as_ref().ok()) | |
168 | } | |
169 | } | |
170 | let x = X(RefCell::new(Ok(7))); | |
171 | let d: Ref<u32> = x.accessor().unwrap(); | |
172 | assert_eq!(*d, 7); | |
173 | } | |
174 | ||
175 | #[test] | |
176 | fn ref_mut_map_accessor() { | |
177 | struct X(RefCell<(u32, char)>); | |
178 | impl X { | |
179 | fn accessor(&self) -> RefMut<u32> { | |
180 | RefMut::map(self.0.borrow_mut(), |tuple| &mut tuple.0) | |
181 | } | |
182 | } | |
183 | let x = X(RefCell::new((7, 'z'))); | |
184 | { | |
185 | let mut d: RefMut<u32> = x.accessor(); | |
186 | assert_eq!(*d, 7); | |
187 | *d += 1; | |
188 | } | |
189 | assert_eq!(*x.0.borrow(), (8, 'z')); | |
190 | } | |
191 | ||
192 | #[test] | |
7453a54e | 193 | #[allow(deprecated)] |
62682a34 SL |
194 | fn ref_mut_filter_map_accessor() { |
195 | struct X(RefCell<Result<u32, ()>>); | |
196 | impl X { | |
197 | fn accessor(&self) -> Option<RefMut<u32>> { | |
198 | RefMut::filter_map(self.0.borrow_mut(), |r| r.as_mut().ok()) | |
199 | } | |
200 | } | |
201 | let x = X(RefCell::new(Ok(7))); | |
202 | { | |
203 | let mut d: RefMut<u32> = x.accessor().unwrap(); | |
204 | assert_eq!(*d, 7); | |
205 | *d += 1; | |
206 | } | |
207 | assert_eq!(*x.0.borrow(), Ok(8)); | |
208 | } | |
209 | ||
1a4d82fc JJ |
210 | #[test] |
211 | fn as_unsafe_cell() { | |
c34b1796 | 212 | let c1: Cell<usize> = Cell::new(0); |
85aaf69f SL |
213 | c1.set(1); |
214 | assert_eq!(1, unsafe { *c1.as_unsafe_cell().get() }); | |
1a4d82fc | 215 | |
c34b1796 | 216 | let c2: Cell<usize> = Cell::new(0); |
85aaf69f SL |
217 | unsafe { *c2.as_unsafe_cell().get() = 1; } |
218 | assert_eq!(1, c2.get()); | |
1a4d82fc | 219 | |
c34b1796 | 220 | let r1: RefCell<usize> = RefCell::new(0); |
85aaf69f SL |
221 | *r1.borrow_mut() = 1; |
222 | assert_eq!(1, unsafe { *r1.as_unsafe_cell().get() }); | |
1a4d82fc | 223 | |
c34b1796 | 224 | let r2: RefCell<usize> = RefCell::new(0); |
85aaf69f SL |
225 | unsafe { *r2.as_unsafe_cell().get() = 1; } |
226 | assert_eq!(1, *r2.borrow()); | |
1a4d82fc JJ |
227 | } |
228 | ||
229 | #[test] | |
230 | fn cell_default() { | |
231 | let cell: Cell<u32> = Default::default(); | |
232 | assert_eq!(0, cell.get()); | |
233 | } | |
234 | ||
235 | #[test] | |
236 | fn refcell_default() { | |
237 | let cell: RefCell<u64> = Default::default(); | |
238 | assert_eq!(0, *cell.borrow()); | |
239 | } | |
d9579d0f AL |
240 | |
241 | #[test] | |
242 | fn unsafe_cell_unsized() { | |
243 | let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]); | |
244 | { | |
245 | let val: &mut [i32] = unsafe { &mut *cell.get() }; | |
246 | val[0] = 4; | |
247 | val[2] = 5; | |
248 | } | |
249 | let comp: &mut [i32] = &mut [4, 2, 5]; | |
250 | assert_eq!(unsafe { &mut *cell.get() }, comp); | |
251 | } | |
252 | ||
b039eaaf SL |
253 | #[test] |
254 | fn refcell_unsized() { | |
255 | let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]); | |
256 | { | |
257 | let b = &mut *cell.borrow_mut(); | |
258 | b[0] = 4; | |
259 | b[2] = 5; | |
260 | } | |
261 | let comp: &mut [i32] = &mut [4, 2, 5]; | |
262 | assert_eq!(&*cell.borrow(), comp); | |
263 | } | |
54a0048b SL |
264 | |
265 | #[test] | |
266 | fn refcell_ref_coercion() { | |
267 | let cell: RefCell<[i32; 3]> = RefCell::new([1, 2, 3]); | |
268 | { | |
269 | let mut cellref: RefMut<[i32; 3]> = cell.borrow_mut(); | |
270 | cellref[0] = 4; | |
271 | let mut coerced: RefMut<[i32]> = cellref; | |
272 | coerced[2] = 5; | |
273 | } | |
274 | { | |
275 | let comp: &mut [i32] = &mut [4, 2, 5]; | |
276 | let cellref: Ref<[i32; 3]> = cell.borrow(); | |
277 | assert_eq!(&*cellref, comp); | |
278 | let coerced: Ref<[i32]> = cellref; | |
279 | assert_eq!(&*coerced, comp); | |
280 | } | |
281 | } | |
282 | ||
283 |