2 use core::default::Default;
6 fn smoketest_unsafe_cell() {
7 let mut x = UnsafeCell::new(10);
10 // The asserts are repeated in order to ensure that `get()`
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);
22 fn unsafe_cell_raw_get() {
23 let x = UnsafeCell::new(10);
24 let ptr = &x as *const UnsafeCell<i32>;
26 // The asserts are repeated in order to ensure that `raw_get()`
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);
39 let x = Cell::new(10);
40 assert_eq!(x, Cell::new(10));
41 assert_eq!(x.get(), 10);
43 assert_eq!(x, Cell::new(20));
44 assert_eq!(x.get(), 20);
46 let y = Cell::new((30, 40));
47 assert_eq!(y, Cell::new((30, 40)));
48 assert_eq!(y.get(), (30, 40));
53 let x = Cell::new(10);
55 assert_eq!(x.update(|x| x + 5), 15);
56 assert_eq!(x.get(), 15);
58 assert_eq!(x.update(|x| x / 3), 5);
59 assert_eq!(x.get(), 5);
63 fn cell_has_sensible_show() {
64 let x = Cell::new("foo bar");
65 assert!(format!("{x:?}").contains(x.get()));
68 assert!(format!("{x:?}").contains(x.get()));
72 fn ref_and_refmut_have_sensible_show() {
73 let refcell = RefCell::new("foo");
75 let refcell_refmut = refcell.borrow_mut();
76 assert_eq!(format!("{refcell_refmut}"), "foo"); // Display
77 assert!(format!("{refcell_refmut:?}").contains("foo")); // Debug
80 let refcell_ref = refcell.borrow();
81 assert_eq!(format!("{refcell_ref}"), "foo"); // Display
82 assert!(format!("{refcell_ref:?}").contains("foo")); // Debug
87 fn double_imm_borrow() {
88 let x = RefCell::new(0);
94 fn no_mut_then_imm_borrow() {
95 let x = RefCell::new(0);
96 let _b1 = x.borrow_mut();
97 assert!(x.try_borrow().is_err());
101 fn no_imm_then_borrow_mut() {
102 let x = RefCell::new(0);
103 let _b1 = x.borrow();
104 assert!(x.try_borrow_mut().is_err());
108 fn no_double_borrow_mut() {
109 let x = RefCell::new(0);
110 assert!(x.try_borrow().is_ok());
111 let _b1 = x.borrow_mut();
112 assert!(x.try_borrow().is_err());
116 fn imm_release_borrow_mut() {
117 let x = RefCell::new(0);
119 let _b1 = x.borrow();
125 fn mut_release_borrow_mut() {
126 let x = RefCell::new(0);
128 let _b1 = x.borrow_mut();
134 fn double_borrow_single_release_no_borrow_mut() {
135 let x = RefCell::new(0);
136 let _b1 = x.borrow();
138 let _b2 = x.borrow();
140 assert!(x.try_borrow().is_ok());
141 assert!(x.try_borrow_mut().is_err());
146 fn discard_doesnt_unborrow() {
147 let x = RefCell::new(0);
150 let _b = x.borrow_mut();
154 fn ref_clone_updates_flag() {
155 let x = RefCell::new(0);
158 assert!(x.try_borrow().is_ok());
159 assert!(x.try_borrow_mut().is_err());
161 let _b2 = Ref::clone(&b1);
162 assert!(x.try_borrow().is_ok());
163 assert!(x.try_borrow_mut().is_err());
165 assert!(x.try_borrow().is_ok());
166 assert!(x.try_borrow_mut().is_err());
168 assert!(x.try_borrow().is_ok());
169 assert!(x.try_borrow_mut().is_ok());
173 fn ref_map_does_not_update_flag() {
174 let x = RefCell::new(Some(5));
176 let b1: Ref<'_, Option<u32>> = x.borrow();
177 assert!(x.try_borrow().is_ok());
178 assert!(x.try_borrow_mut().is_err());
180 let b2: Ref<'_, u32> = Ref::map(b1, |o| o.as_ref().unwrap());
182 assert!(x.try_borrow().is_ok());
183 assert!(x.try_borrow_mut().is_err());
185 assert!(x.try_borrow().is_ok());
186 assert!(x.try_borrow_mut().is_ok());
188 assert!(x.try_borrow().is_ok());
189 assert!(x.try_borrow_mut().is_ok());
193 fn ref_map_split_updates_flag() {
194 let x = RefCell::new([1, 2]);
197 assert!(x.try_borrow().is_ok());
198 assert!(x.try_borrow_mut().is_err());
200 let (_b2, _b3) = Ref::map_split(b1, |slc| slc.split_at(1));
201 assert!(x.try_borrow().is_ok());
202 assert!(x.try_borrow_mut().is_err());
204 assert!(x.try_borrow().is_ok());
205 assert!(x.try_borrow_mut().is_ok());
207 assert!(x.try_borrow().is_ok());
208 assert!(x.try_borrow_mut().is_ok());
211 let b1 = x.borrow_mut();
212 assert!(x.try_borrow().is_err());
213 assert!(x.try_borrow_mut().is_err());
215 let (_b2, _b3) = RefMut::map_split(b1, |slc| slc.split_at_mut(1));
216 assert!(x.try_borrow().is_err());
217 assert!(x.try_borrow_mut().is_err());
219 assert!(x.try_borrow().is_err());
220 assert!(x.try_borrow_mut().is_err());
222 assert!(x.try_borrow().is_ok());
223 assert!(x.try_borrow_mut().is_ok());
225 assert!(x.try_borrow().is_ok());
226 assert!(x.try_borrow_mut().is_ok());
231 let x = RefCell::new([1, 2]);
232 let (b1, b2) = Ref::map_split(x.borrow(), |slc| slc.split_at(1));
233 assert_eq!(*b1, [1]);
234 assert_eq!(*b2, [2]);
238 fn ref_mut_map_split() {
239 let x = RefCell::new([1, 2]);
241 let (mut b1, mut b2) = RefMut::map_split(x.borrow_mut(), |slc| slc.split_at_mut(1));
242 assert_eq!(*b1, [1]);
243 assert_eq!(*b2, [2]);
247 assert_eq!(*x.borrow(), [2, 1]);
251 fn ref_map_accessor() {
252 struct X(RefCell<(u32, char)>);
254 fn accessor(&self) -> Ref<'_, u32> {
255 Ref::map(self.0.borrow(), |tuple| &tuple.0)
258 let x = X(RefCell::new((7, 'z')));
259 let d: Ref<'_, u32> = x.accessor();
264 fn ref_mut_map_accessor() {
265 struct X(RefCell<(u32, char)>);
267 fn accessor(&self) -> RefMut<'_, u32> {
268 RefMut::map(self.0.borrow_mut(), |tuple| &mut tuple.0)
271 let x = X(RefCell::new((7, 'z')));
273 let mut d: RefMut<'_, u32> = x.accessor();
277 assert_eq!(*x.0.borrow(), (8, 'z'));
282 let c1: Cell<usize> = Cell::new(0);
284 assert_eq!(1, unsafe { *c1.as_ptr() });
286 let c2: Cell<usize> = Cell::new(0);
290 assert_eq!(1, c2.get());
292 let r1: RefCell<usize> = RefCell::new(0);
293 *r1.borrow_mut() = 1;
294 assert_eq!(1, unsafe { *r1.as_ptr() });
296 let r2: RefCell<usize> = RefCell::new(0);
300 assert_eq!(1, *r2.borrow());
305 let cell: Cell<u32> = Default::default();
306 assert_eq!(0, cell.get());
311 let cell = Cell::new(10);
313 assert_eq!(20, cell.get());
315 let cell = Cell::new("Hello".to_owned());
316 cell.set("World".to_owned());
317 assert_eq!("World".to_owned(), cell.into_inner());
322 let cell = Cell::new(10);
323 assert_eq!(10, cell.replace(20));
324 assert_eq!(20, cell.get());
326 let cell = Cell::new("Hello".to_owned());
327 assert_eq!("Hello".to_owned(), cell.replace("World".to_owned()));
328 assert_eq!("World".to_owned(), cell.into_inner());
332 fn cell_into_inner() {
333 let cell = Cell::new(10);
334 assert_eq!(10, cell.into_inner());
336 let cell = Cell::new("Hello world".to_owned());
337 assert_eq!("Hello world".to_owned(), cell.into_inner());
342 #[derive(Copy, Clone)]
350 fn f(p: &Cell<Point>) {
351 assert_eq!(p.get().z, 12);
352 p.set(Point { x: 10, y: 11, z: 13 });
353 assert_eq!(p.get().z, 13);
356 let a = Point { x: 10, y: 11, z: 12 };
357 let b = &Cell::new(a);
358 assert_eq!(b.get().z, 12);
361 assert_eq!(b.get().z, 13);
365 fn cell_does_not_clone() {
373 fn clone(&self) -> Foo {
374 // Using Cell in any way should never cause clone() to be
375 // invoked -- after all, that would permit evil user code to
376 // abuse `Cell` and trigger crashes.
382 let x = Cell::new(Foo { x: 22 });
388 fn refcell_default() {
389 let cell: RefCell<u64> = Default::default();
390 assert_eq!(0, *cell.borrow());
394 fn unsafe_cell_unsized() {
395 let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]);
397 let val: &mut [i32] = unsafe { &mut *cell.get() };
401 let comp: &mut [i32] = &mut [4, 2, 5];
402 assert_eq!(unsafe { &mut *cell.get() }, comp);
406 fn refcell_unsized() {
407 let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
409 let b = &mut *cell.borrow_mut();
413 let comp: &mut [i32] = &mut [4, 2, 5];
414 assert_eq!(&*cell.borrow(), comp);
418 fn refcell_ref_coercion() {
419 let cell: RefCell<[i32; 3]> = RefCell::new([1, 2, 3]);
421 let mut cellref: RefMut<'_, [i32; 3]> = cell.borrow_mut();
423 let mut coerced: RefMut<'_, [i32]> = cellref;
427 let comp: &mut [i32] = &mut [4, 2, 5];
428 let cellref: Ref<'_, [i32; 3]> = cell.borrow();
429 assert_eq!(&*cellref, comp);
430 let coerced: Ref<'_, [i32]> = cellref;
431 assert_eq!(&*coerced, comp);
437 fn refcell_swap_borrows() {
438 let x = RefCell::new(0);
440 let y = RefCell::new(1);
446 fn refcell_replace_borrows() {
447 let x = RefCell::new(0);
453 fn refcell_format() {
454 let name = RefCell::new("rust");
455 let what = RefCell::new("rocks");
456 let msg = format!("{name} {}", &*what.borrow(), name = &*name.borrow());
457 assert_eq!(msg, "rust rocks".to_string());
462 const UNSAFE_CELL: UnsafeCell<i32> = UnsafeCell::new(3);
463 const _: i32 = UNSAFE_CELL.into_inner();
465 const REF_CELL: RefCell<i32> = RefCell::new(3);
466 const _: i32 = REF_CELL.into_inner();
468 const CELL: Cell<i32> = Cell::new(3);
469 const _: i32 = CELL.into_inner();
471 const UNSAFE_CELL_FROM: UnsafeCell<i32> = UnsafeCell::from(3);
472 const _: i32 = UNSAFE_CELL.into_inner();
474 const REF_CELL_FROM: RefCell<i32> = RefCell::from(3);
475 const _: i32 = REF_CELL.into_inner();
477 const CELL_FROM: Cell<i32> = Cell::from(3);
478 const _: i32 = CELL.into_inner();