]> git.proxmox.com Git - rustc.git/blame - library/core/tests/cell.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / library / core / tests / cell.rs
CommitLineData
1a4d82fc
JJ
1use core::cell::*;
2use core::default::Default;
3use std::mem::drop;
4
94222f64
XL
5#[test]
6fn 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]
22fn 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]
38fn 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]
52fn 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]
63fn cell_has_sensible_show() {
64 let x = Cell::new("foo bar");
ee023bcb 65 assert!(format!("{x:?}").contains(x.get()));
1a4d82fc
JJ
66
67 x.set("baz qux");
ee023bcb 68 assert!(format!("{x:?}").contains(x.get()));
1a4d82fc
JJ
69}
70
71#[test]
72fn ref_and_refmut_have_sensible_show() {
73 let refcell = RefCell::new("foo");
74
75 let refcell_refmut = refcell.borrow_mut();
ee023bcb 76 assert!(format!("{refcell_refmut:?}").contains("foo"));
1a4d82fc
JJ
77 drop(refcell_refmut);
78
79 let refcell_ref = refcell.borrow();
ee023bcb 80 assert!(format!("{refcell_ref:?}").contains("foo"));
1a4d82fc
JJ
81 drop(refcell_ref);
82}
83
84#[test]
85fn double_imm_borrow() {
85aaf69f 86 let x = RefCell::new(0);
1a4d82fc
JJ
87 let _b1 = x.borrow();
88 x.borrow();
89}
90
91#[test]
92fn 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]
99fn 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]
106fn 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]
114fn 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]
123fn 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]
132fn 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 144fn 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 152fn 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]
171fn 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]
191fn 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]
228fn 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]
236fn 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]
249fn 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]
262fn 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 279fn 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]
302fn cell_default() {
303 let cell: Cell<u32> = Default::default();
304 assert_eq!(0, cell.get());
305}
306
8bb4bdeb
XL
307#[test]
308fn 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]
319fn 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]
330fn 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]
339fn 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]
363fn 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]
386fn refcell_default() {
387 let cell: RefCell<u64> = Default::default();
388 assert_eq!(0, *cell.borrow());
389}
d9579d0f
AL
390
391#[test]
392fn 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]
404fn 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]
416fn 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]
435fn 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]
444fn refcell_replace_borrows() {
445 let x = RefCell::new(0);
446 let _b = x.borrow();
447 x.replace(1);
448}
1b1a35ee
XL
449
450#[test]
451fn 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)]
459fn 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();
3c0e092e
XL
468
469 const UNSAFE_CELL_FROM: UnsafeCell<i32> = UnsafeCell::from(3);
470 const _: i32 = UNSAFE_CELL.into_inner();
471
472 const REF_CELL_FROM: RefCell<i32> = RefCell::from(3);
473 const _: i32 = REF_CELL.into_inner();
474
475 const CELL_FROM: Cell<i32> = Cell::from(3);
476 const _: i32 = CELL.into_inner();
29967ef6 477}