]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | use core::cell::*; |
2 | use core::default::Default; | |
3 | use std::mem::drop; | |
4 | ||
94222f64 XL |
5 | #[test] |
6 | fn smoketest_unsafe_cell() { | |
7 | let mut x = UnsafeCell::new(10); | |
8 | let ref_mut = &mut x; | |
9 | unsafe { | |
10 | // The asserts are repeated in order to ensure that `get()` | |
11 | // is non-mutating. | |
12 | assert_eq!(*ref_mut.get(), 10); | |
13 | assert_eq!(*ref_mut.get(), 10); | |
14 | *ref_mut.get_mut() += 5; | |
15 | assert_eq!(*ref_mut.get(), 15); | |
16 | assert_eq!(*ref_mut.get(), 15); | |
17 | assert_eq!(x.into_inner(), 15); | |
18 | } | |
19 | } | |
20 | ||
21 | #[test] | |
22 | fn unsafe_cell_raw_get() { | |
23 | let x = UnsafeCell::new(10); | |
24 | let ptr = &x as *const UnsafeCell<i32>; | |
25 | unsafe { | |
26 | // The asserts are repeated in order to ensure that `raw_get()` | |
27 | // is non-mutating. | |
28 | assert_eq!(*UnsafeCell::raw_get(ptr), 10); | |
29 | assert_eq!(*UnsafeCell::raw_get(ptr), 10); | |
30 | *UnsafeCell::raw_get(ptr) += 5; | |
31 | assert_eq!(*UnsafeCell::raw_get(ptr), 15); | |
32 | assert_eq!(*UnsafeCell::raw_get(ptr), 15); | |
33 | assert_eq!(x.into_inner(), 15); | |
34 | } | |
35 | } | |
36 | ||
1a4d82fc JJ |
37 | #[test] |
38 | fn smoketest_cell() { | |
85aaf69f | 39 | let x = Cell::new(10); |
532ac7d7 XL |
40 | assert_eq!(x, Cell::new(10)); |
41 | assert_eq!(x.get(), 10); | |
1a4d82fc | 42 | x.set(20); |
532ac7d7 XL |
43 | assert_eq!(x, Cell::new(20)); |
44 | assert_eq!(x.get(), 20); | |
1a4d82fc | 45 | |
85aaf69f | 46 | let y = Cell::new((30, 40)); |
532ac7d7 XL |
47 | assert_eq!(y, Cell::new((30, 40))); |
48 | assert_eq!(y.get(), (30, 40)); | |
1a4d82fc JJ |
49 | } |
50 | ||
83c7162d XL |
51 | #[test] |
52 | fn cell_update() { | |
53 | let x = Cell::new(10); | |
54 | ||
55 | assert_eq!(x.update(|x| x + 5), 15); | |
56 | assert_eq!(x.get(), 15); | |
57 | ||
58 | assert_eq!(x.update(|x| x / 3), 5); | |
59 | assert_eq!(x.get(), 5); | |
60 | } | |
61 | ||
1a4d82fc JJ |
62 | #[test] |
63 | fn cell_has_sensible_show() { | |
64 | let x = Cell::new("foo bar"); | |
65 | assert!(format!("{:?}", x).contains(x.get())); | |
66 | ||
67 | x.set("baz qux"); | |
68 | assert!(format!("{:?}", x).contains(x.get())); | |
69 | } | |
70 | ||
71 | #[test] | |
72 | fn ref_and_refmut_have_sensible_show() { | |
73 | let refcell = RefCell::new("foo"); | |
74 | ||
75 | let refcell_refmut = refcell.borrow_mut(); | |
76 | assert!(format!("{:?}", refcell_refmut).contains("foo")); | |
77 | drop(refcell_refmut); | |
78 | ||
79 | let refcell_ref = refcell.borrow(); | |
80 | assert!(format!("{:?}", refcell_ref).contains("foo")); | |
81 | drop(refcell_ref); | |
82 | } | |
83 | ||
84 | #[test] | |
85 | fn double_imm_borrow() { | |
85aaf69f | 86 | let x = RefCell::new(0); |
1a4d82fc JJ |
87 | let _b1 = x.borrow(); |
88 | x.borrow(); | |
89 | } | |
90 | ||
91 | #[test] | |
92 | fn no_mut_then_imm_borrow() { | |
85aaf69f | 93 | let x = RefCell::new(0); |
1a4d82fc | 94 | let _b1 = x.borrow_mut(); |
476ff2be | 95 | assert!(x.try_borrow().is_err()); |
1a4d82fc JJ |
96 | } |
97 | ||
98 | #[test] | |
99 | fn no_imm_then_borrow_mut() { | |
85aaf69f | 100 | let x = RefCell::new(0); |
1a4d82fc | 101 | let _b1 = x.borrow(); |
476ff2be | 102 | assert!(x.try_borrow_mut().is_err()); |
1a4d82fc JJ |
103 | } |
104 | ||
105 | #[test] | |
106 | fn no_double_borrow_mut() { | |
85aaf69f | 107 | let x = RefCell::new(0); |
476ff2be | 108 | assert!(x.try_borrow().is_ok()); |
1a4d82fc | 109 | let _b1 = x.borrow_mut(); |
476ff2be | 110 | assert!(x.try_borrow().is_err()); |
1a4d82fc JJ |
111 | } |
112 | ||
113 | #[test] | |
114 | fn imm_release_borrow_mut() { | |
85aaf69f | 115 | let x = RefCell::new(0); |
1a4d82fc JJ |
116 | { |
117 | let _b1 = x.borrow(); | |
118 | } | |
119 | x.borrow_mut(); | |
120 | } | |
121 | ||
122 | #[test] | |
123 | fn mut_release_borrow_mut() { | |
85aaf69f | 124 | let x = RefCell::new(0); |
1a4d82fc JJ |
125 | { |
126 | let _b1 = x.borrow_mut(); | |
127 | } | |
128 | x.borrow(); | |
129 | } | |
130 | ||
131 | #[test] | |
132 | fn double_borrow_single_release_no_borrow_mut() { | |
85aaf69f | 133 | let x = RefCell::new(0); |
1a4d82fc JJ |
134 | let _b1 = x.borrow(); |
135 | { | |
136 | let _b2 = x.borrow(); | |
137 | } | |
476ff2be SL |
138 | assert!(x.try_borrow().is_ok()); |
139 | assert!(x.try_borrow_mut().is_err()); | |
1a4d82fc JJ |
140 | } |
141 | ||
142 | #[test] | |
c34b1796 | 143 | #[should_panic] |
1a4d82fc | 144 | fn discard_doesnt_unborrow() { |
85aaf69f | 145 | let x = RefCell::new(0); |
1a4d82fc JJ |
146 | let _b = x.borrow(); |
147 | let _ = _b; | |
148 | let _b = x.borrow_mut(); | |
149 | } | |
150 | ||
151 | #[test] | |
62682a34 | 152 | fn ref_clone_updates_flag() { |
85aaf69f | 153 | let x = RefCell::new(0); |
1a4d82fc JJ |
154 | { |
155 | let b1 = x.borrow(); | |
476ff2be SL |
156 | assert!(x.try_borrow().is_ok()); |
157 | assert!(x.try_borrow_mut().is_err()); | |
1a4d82fc | 158 | { |
62682a34 | 159 | let _b2 = Ref::clone(&b1); |
476ff2be SL |
160 | assert!(x.try_borrow().is_ok()); |
161 | assert!(x.try_borrow_mut().is_err()); | |
1a4d82fc | 162 | } |
476ff2be SL |
163 | assert!(x.try_borrow().is_ok()); |
164 | assert!(x.try_borrow_mut().is_err()); | |
1a4d82fc | 165 | } |
476ff2be SL |
166 | assert!(x.try_borrow().is_ok()); |
167 | assert!(x.try_borrow_mut().is_ok()); | |
1a4d82fc JJ |
168 | } |
169 | ||
62682a34 SL |
170 | #[test] |
171 | fn ref_map_does_not_update_flag() { | |
172 | let x = RefCell::new(Some(5)); | |
173 | { | |
48663c56 | 174 | let b1: Ref<'_, Option<u32>> = x.borrow(); |
476ff2be SL |
175 | assert!(x.try_borrow().is_ok()); |
176 | assert!(x.try_borrow_mut().is_err()); | |
62682a34 | 177 | { |
48663c56 | 178 | let b2: Ref<'_, u32> = Ref::map(b1, |o| o.as_ref().unwrap()); |
62682a34 | 179 | assert_eq!(*b2, 5); |
476ff2be SL |
180 | assert!(x.try_borrow().is_ok()); |
181 | assert!(x.try_borrow_mut().is_err()); | |
62682a34 | 182 | } |
476ff2be SL |
183 | assert!(x.try_borrow().is_ok()); |
184 | assert!(x.try_borrow_mut().is_ok()); | |
62682a34 | 185 | } |
476ff2be SL |
186 | assert!(x.try_borrow().is_ok()); |
187 | assert!(x.try_borrow_mut().is_ok()); | |
62682a34 SL |
188 | } |
189 | ||
94b46f34 XL |
190 | #[test] |
191 | fn ref_map_split_updates_flag() { | |
192 | let x = RefCell::new([1, 2]); | |
193 | { | |
194 | let b1 = x.borrow(); | |
195 | assert!(x.try_borrow().is_ok()); | |
196 | assert!(x.try_borrow_mut().is_err()); | |
197 | { | |
198 | let (_b2, _b3) = Ref::map_split(b1, |slc| slc.split_at(1)); | |
199 | assert!(x.try_borrow().is_ok()); | |
200 | assert!(x.try_borrow_mut().is_err()); | |
201 | } | |
202 | assert!(x.try_borrow().is_ok()); | |
203 | assert!(x.try_borrow_mut().is_ok()); | |
204 | } | |
205 | assert!(x.try_borrow().is_ok()); | |
206 | assert!(x.try_borrow_mut().is_ok()); | |
207 | ||
208 | { | |
209 | let b1 = x.borrow_mut(); | |
210 | assert!(x.try_borrow().is_err()); | |
211 | assert!(x.try_borrow_mut().is_err()); | |
212 | { | |
213 | let (_b2, _b3) = RefMut::map_split(b1, |slc| slc.split_at_mut(1)); | |
214 | assert!(x.try_borrow().is_err()); | |
215 | assert!(x.try_borrow_mut().is_err()); | |
216 | drop(_b2); | |
217 | assert!(x.try_borrow().is_err()); | |
218 | assert!(x.try_borrow_mut().is_err()); | |
219 | } | |
220 | assert!(x.try_borrow().is_ok()); | |
221 | assert!(x.try_borrow_mut().is_ok()); | |
222 | } | |
223 | assert!(x.try_borrow().is_ok()); | |
224 | assert!(x.try_borrow_mut().is_ok()); | |
225 | } | |
226 | ||
227 | #[test] | |
228 | fn ref_map_split() { | |
229 | let x = RefCell::new([1, 2]); | |
230 | let (b1, b2) = Ref::map_split(x.borrow(), |slc| slc.split_at(1)); | |
231 | assert_eq!(*b1, [1]); | |
232 | assert_eq!(*b2, [2]); | |
233 | } | |
234 | ||
235 | #[test] | |
236 | fn ref_mut_map_split() { | |
237 | let x = RefCell::new([1, 2]); | |
238 | { | |
239 | let (mut b1, mut b2) = RefMut::map_split(x.borrow_mut(), |slc| slc.split_at_mut(1)); | |
240 | assert_eq!(*b1, [1]); | |
241 | assert_eq!(*b2, [2]); | |
242 | b1[0] = 2; | |
243 | b2[0] = 1; | |
244 | } | |
245 | assert_eq!(*x.borrow(), [2, 1]); | |
246 | } | |
247 | ||
62682a34 SL |
248 | #[test] |
249 | fn ref_map_accessor() { | |
250 | struct X(RefCell<(u32, char)>); | |
251 | impl X { | |
48663c56 | 252 | fn accessor(&self) -> Ref<'_, u32> { |
62682a34 SL |
253 | Ref::map(self.0.borrow(), |tuple| &tuple.0) |
254 | } | |
255 | } | |
256 | let x = X(RefCell::new((7, 'z'))); | |
48663c56 | 257 | let d: Ref<'_, u32> = x.accessor(); |
62682a34 SL |
258 | assert_eq!(*d, 7); |
259 | } | |
260 | ||
62682a34 SL |
261 | #[test] |
262 | fn ref_mut_map_accessor() { | |
263 | struct X(RefCell<(u32, char)>); | |
264 | impl X { | |
48663c56 | 265 | fn accessor(&self) -> RefMut<'_, u32> { |
62682a34 SL |
266 | RefMut::map(self.0.borrow_mut(), |tuple| &mut tuple.0) |
267 | } | |
268 | } | |
269 | let x = X(RefCell::new((7, 'z'))); | |
270 | { | |
60c5eb7d | 271 | let mut d: RefMut<'_, u32> = x.accessor(); |
62682a34 SL |
272 | assert_eq!(*d, 7); |
273 | *d += 1; | |
274 | } | |
275 | assert_eq!(*x.0.borrow(), (8, 'z')); | |
276 | } | |
277 | ||
1a4d82fc | 278 | #[test] |
5bcae85e | 279 | fn as_ptr() { |
c34b1796 | 280 | let c1: Cell<usize> = Cell::new(0); |
85aaf69f | 281 | c1.set(1); |
5bcae85e | 282 | assert_eq!(1, unsafe { *c1.as_ptr() }); |
1a4d82fc | 283 | |
c34b1796 | 284 | let c2: Cell<usize> = Cell::new(0); |
60c5eb7d XL |
285 | unsafe { |
286 | *c2.as_ptr() = 1; | |
287 | } | |
85aaf69f | 288 | assert_eq!(1, c2.get()); |
1a4d82fc | 289 | |
c34b1796 | 290 | let r1: RefCell<usize> = RefCell::new(0); |
85aaf69f | 291 | *r1.borrow_mut() = 1; |
5bcae85e | 292 | assert_eq!(1, unsafe { *r1.as_ptr() }); |
1a4d82fc | 293 | |
c34b1796 | 294 | let r2: RefCell<usize> = RefCell::new(0); |
60c5eb7d XL |
295 | unsafe { |
296 | *r2.as_ptr() = 1; | |
297 | } | |
85aaf69f | 298 | assert_eq!(1, *r2.borrow()); |
1a4d82fc JJ |
299 | } |
300 | ||
301 | #[test] | |
302 | fn cell_default() { | |
303 | let cell: Cell<u32> = Default::default(); | |
304 | assert_eq!(0, cell.get()); | |
305 | } | |
306 | ||
8bb4bdeb XL |
307 | #[test] |
308 | fn cell_set() { | |
309 | let cell = Cell::new(10); | |
310 | cell.set(20); | |
311 | assert_eq!(20, cell.get()); | |
312 | ||
313 | let cell = Cell::new("Hello".to_owned()); | |
314 | cell.set("World".to_owned()); | |
315 | assert_eq!("World".to_owned(), cell.into_inner()); | |
316 | } | |
317 | ||
318 | #[test] | |
319 | fn cell_replace() { | |
320 | let cell = Cell::new(10); | |
321 | assert_eq!(10, cell.replace(20)); | |
322 | assert_eq!(20, cell.get()); | |
323 | ||
324 | let cell = Cell::new("Hello".to_owned()); | |
325 | assert_eq!("Hello".to_owned(), cell.replace("World".to_owned())); | |
326 | assert_eq!("World".to_owned(), cell.into_inner()); | |
327 | } | |
328 | ||
329 | #[test] | |
330 | fn cell_into_inner() { | |
331 | let cell = Cell::new(10); | |
332 | assert_eq!(10, cell.into_inner()); | |
333 | ||
334 | let cell = Cell::new("Hello world".to_owned()); | |
335 | assert_eq!("Hello world".to_owned(), cell.into_inner()); | |
336 | } | |
337 | ||
1b1a35ee XL |
338 | #[test] |
339 | fn cell_exterior() { | |
340 | #[derive(Copy, Clone)] | |
341 | #[allow(dead_code)] | |
342 | struct Point { | |
343 | x: isize, | |
344 | y: isize, | |
345 | z: isize, | |
346 | } | |
347 | ||
348 | fn f(p: &Cell<Point>) { | |
349 | assert_eq!(p.get().z, 12); | |
350 | p.set(Point { x: 10, y: 11, z: 13 }); | |
351 | assert_eq!(p.get().z, 13); | |
352 | } | |
353 | ||
354 | let a = Point { x: 10, y: 11, z: 12 }; | |
355 | let b = &Cell::new(a); | |
356 | assert_eq!(b.get().z, 12); | |
357 | f(b); | |
358 | assert_eq!(a.z, 12); | |
359 | assert_eq!(b.get().z, 13); | |
360 | } | |
361 | ||
362 | #[test] | |
363 | fn cell_does_not_clone() { | |
364 | #[derive(Copy)] | |
365 | #[allow(dead_code)] | |
366 | struct Foo { | |
367 | x: isize, | |
368 | } | |
369 | ||
370 | impl Clone for Foo { | |
371 | fn clone(&self) -> Foo { | |
372 | // Using Cell in any way should never cause clone() to be | |
373 | // invoked -- after all, that would permit evil user code to | |
374 | // abuse `Cell` and trigger crashes. | |
375 | ||
376 | panic!(); | |
377 | } | |
378 | } | |
379 | ||
380 | let x = Cell::new(Foo { x: 22 }); | |
381 | let _y = x.get(); | |
382 | let _z = x.clone(); | |
383 | } | |
384 | ||
1a4d82fc JJ |
385 | #[test] |
386 | fn refcell_default() { | |
387 | let cell: RefCell<u64> = Default::default(); | |
388 | assert_eq!(0, *cell.borrow()); | |
389 | } | |
d9579d0f AL |
390 | |
391 | #[test] | |
392 | fn unsafe_cell_unsized() { | |
393 | let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]); | |
394 | { | |
395 | let val: &mut [i32] = unsafe { &mut *cell.get() }; | |
396 | val[0] = 4; | |
397 | val[2] = 5; | |
398 | } | |
399 | let comp: &mut [i32] = &mut [4, 2, 5]; | |
400 | assert_eq!(unsafe { &mut *cell.get() }, comp); | |
401 | } | |
402 | ||
b039eaaf SL |
403 | #[test] |
404 | fn refcell_unsized() { | |
405 | let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]); | |
406 | { | |
407 | let b = &mut *cell.borrow_mut(); | |
408 | b[0] = 4; | |
409 | b[2] = 5; | |
410 | } | |
411 | let comp: &mut [i32] = &mut [4, 2, 5]; | |
412 | assert_eq!(&*cell.borrow(), comp); | |
413 | } | |
54a0048b SL |
414 | |
415 | #[test] | |
416 | fn refcell_ref_coercion() { | |
417 | let cell: RefCell<[i32; 3]> = RefCell::new([1, 2, 3]); | |
418 | { | |
48663c56 | 419 | let mut cellref: RefMut<'_, [i32; 3]> = cell.borrow_mut(); |
54a0048b | 420 | cellref[0] = 4; |
48663c56 | 421 | let mut coerced: RefMut<'_, [i32]> = cellref; |
54a0048b SL |
422 | coerced[2] = 5; |
423 | } | |
424 | { | |
425 | let comp: &mut [i32] = &mut [4, 2, 5]; | |
48663c56 | 426 | let cellref: Ref<'_, [i32; 3]> = cell.borrow(); |
54a0048b | 427 | assert_eq!(&*cellref, comp); |
48663c56 | 428 | let coerced: Ref<'_, [i32]> = cellref; |
54a0048b SL |
429 | assert_eq!(&*coerced, comp); |
430 | } | |
431 | } | |
3b2f2976 XL |
432 | |
433 | #[test] | |
434 | #[should_panic] | |
435 | fn refcell_swap_borrows() { | |
436 | let x = RefCell::new(0); | |
437 | let _b = x.borrow(); | |
438 | let y = RefCell::new(1); | |
439 | x.swap(&y); | |
440 | } | |
441 | ||
442 | #[test] | |
443 | #[should_panic] | |
444 | fn refcell_replace_borrows() { | |
445 | let x = RefCell::new(0); | |
446 | let _b = x.borrow(); | |
447 | x.replace(1); | |
448 | } | |
1b1a35ee XL |
449 | |
450 | #[test] | |
451 | fn refcell_format() { | |
452 | let name = RefCell::new("rust"); | |
453 | let what = RefCell::new("rocks"); | |
454 | let msg = format!("{name} {}", &*what.borrow(), name = &*name.borrow()); | |
455 | assert_eq!(msg, "rust rocks".to_string()); | |
456 | } | |
29967ef6 XL |
457 | |
458 | #[allow(dead_code)] | |
459 | fn const_cells() { | |
460 | const UNSAFE_CELL: UnsafeCell<i32> = UnsafeCell::new(3); | |
461 | const _: i32 = UNSAFE_CELL.into_inner(); | |
462 | ||
463 | const REF_CELL: RefCell<i32> = RefCell::new(3); | |
464 | const _: i32 = REF_CELL.into_inner(); | |
465 | ||
466 | const CELL: Cell<i32> = Cell::new(3); | |
467 | const _: i32 = CELL.into_inner(); | |
468 | } |