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