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
!(format
!("{refcell_refmut:?}").contains("foo"));
79 let refcell_ref
= refcell
.borrow();
80 assert
!(format
!("{refcell_ref:?}").contains("foo"));
85 fn double_imm_borrow() {
86 let x
= RefCell
::new(0);
92 fn no_mut_then_imm_borrow() {
93 let x
= RefCell
::new(0);
94 let _b1
= x
.borrow_mut();
95 assert
!(x
.try_borrow().is_err());
99 fn no_imm_then_borrow_mut() {
100 let x
= RefCell
::new(0);
101 let _b1
= x
.borrow();
102 assert
!(x
.try_borrow_mut().is_err());
106 fn no_double_borrow_mut() {
107 let x
= RefCell
::new(0);
108 assert
!(x
.try_borrow().is_ok());
109 let _b1
= x
.borrow_mut();
110 assert
!(x
.try_borrow().is_err());
114 fn imm_release_borrow_mut() {
115 let x
= RefCell
::new(0);
117 let _b1
= x
.borrow();
123 fn mut_release_borrow_mut() {
124 let x
= RefCell
::new(0);
126 let _b1
= x
.borrow_mut();
132 fn double_borrow_single_release_no_borrow_mut() {
133 let x
= RefCell
::new(0);
134 let _b1
= x
.borrow();
136 let _b2
= x
.borrow();
138 assert
!(x
.try_borrow().is_ok());
139 assert
!(x
.try_borrow_mut().is_err());
144 fn discard_doesnt_unborrow() {
145 let x
= RefCell
::new(0);
148 let _b
= x
.borrow_mut();
152 fn ref_clone_updates_flag() {
153 let x
= RefCell
::new(0);
156 assert
!(x
.try_borrow().is_ok());
157 assert
!(x
.try_borrow_mut().is_err());
159 let _b2
= Ref
::clone(&b1
);
160 assert
!(x
.try_borrow().is_ok());
161 assert
!(x
.try_borrow_mut().is_err());
163 assert
!(x
.try_borrow().is_ok());
164 assert
!(x
.try_borrow_mut().is_err());
166 assert
!(x
.try_borrow().is_ok());
167 assert
!(x
.try_borrow_mut().is_ok());
171 fn ref_map_does_not_update_flag() {
172 let x
= RefCell
::new(Some(5));
174 let b1
: Ref
<'_
, Option
<u32>> = x
.borrow();
175 assert
!(x
.try_borrow().is_ok());
176 assert
!(x
.try_borrow_mut().is_err());
178 let b2
: Ref
<'_
, u32> = Ref
::map(b1
, |o
| o
.as_ref().unwrap());
180 assert
!(x
.try_borrow().is_ok());
181 assert
!(x
.try_borrow_mut().is_err());
183 assert
!(x
.try_borrow().is_ok());
184 assert
!(x
.try_borrow_mut().is_ok());
186 assert
!(x
.try_borrow().is_ok());
187 assert
!(x
.try_borrow_mut().is_ok());
191 fn ref_map_split_updates_flag() {
192 let x
= RefCell
::new([1, 2]);
195 assert
!(x
.try_borrow().is_ok());
196 assert
!(x
.try_borrow_mut().is_err());
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());
202 assert
!(x
.try_borrow().is_ok());
203 assert
!(x
.try_borrow_mut().is_ok());
205 assert
!(x
.try_borrow().is_ok());
206 assert
!(x
.try_borrow_mut().is_ok());
209 let b1
= x
.borrow_mut();
210 assert
!(x
.try_borrow().is_err());
211 assert
!(x
.try_borrow_mut().is_err());
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());
217 assert
!(x
.try_borrow().is_err());
218 assert
!(x
.try_borrow_mut().is_err());
220 assert
!(x
.try_borrow().is_ok());
221 assert
!(x
.try_borrow_mut().is_ok());
223 assert
!(x
.try_borrow().is_ok());
224 assert
!(x
.try_borrow_mut().is_ok());
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]);
236 fn ref_mut_map_split() {
237 let x
= RefCell
::new([1, 2]);
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]);
245 assert_eq
!(*x
.borrow(), [2, 1]);
249 fn ref_map_accessor() {
250 struct X(RefCell
<(u32, char)>);
252 fn accessor(&self) -> Ref
<'_
, u32> {
253 Ref
::map(self.0.borrow(), |tuple
| &tuple
.0)
256 let x
= X(RefCell
::new((7, 'z'
)));
257 let d
: Ref
<'_
, u32> = x
.accessor();
262 fn ref_mut_map_accessor() {
263 struct X(RefCell
<(u32, char)>);
265 fn accessor(&self) -> RefMut
<'_
, u32> {
266 RefMut
::map(self.0.borrow_mut(), |tuple
| &mut tuple
.0)
269 let x
= X(RefCell
::new((7, 'z'
)));
271 let mut d
: RefMut
<'_
, u32> = x
.accessor();
275 assert_eq
!(*x
.0.borrow(), (8, 'z'
));
280 let c1
: Cell
<usize> = Cell
::new(0);
282 assert_eq
!(1, unsafe { *c1.as_ptr() }
);
284 let c2
: Cell
<usize> = Cell
::new(0);
288 assert_eq
!(1, c2
.get());
290 let r1
: RefCell
<usize> = RefCell
::new(0);
291 *r1
.borrow_mut() = 1;
292 assert_eq
!(1, unsafe { *r1.as_ptr() }
);
294 let r2
: RefCell
<usize> = RefCell
::new(0);
298 assert_eq
!(1, *r2
.borrow());
303 let cell
: Cell
<u32> = Default
::default();
304 assert_eq
!(0, cell
.get());
309 let cell
= Cell
::new(10);
311 assert_eq
!(20, cell
.get());
313 let cell
= Cell
::new("Hello".to_owned());
314 cell
.set("World".to_owned());
315 assert_eq
!("World".to_owned(), cell
.into_inner());
320 let cell
= Cell
::new(10);
321 assert_eq
!(10, cell
.replace(20));
322 assert_eq
!(20, cell
.get());
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());
330 fn cell_into_inner() {
331 let cell
= Cell
::new(10);
332 assert_eq
!(10, cell
.into_inner());
334 let cell
= Cell
::new("Hello world".to_owned());
335 assert_eq
!("Hello world".to_owned(), cell
.into_inner());
340 #[derive(Copy, Clone)]
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);
354 let a
= Point { x: 10, y: 11, z: 12 }
;
355 let b
= &Cell
::new(a
);
356 assert_eq
!(b
.get().z
, 12);
359 assert_eq
!(b
.get().z
, 13);
363 fn cell_does_not_clone() {
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.
380 let x
= Cell
::new(Foo { x: 22 }
);
386 fn refcell_default() {
387 let cell
: RefCell
<u64> = Default
::default();
388 assert_eq
!(0, *cell
.borrow());
392 fn unsafe_cell_unsized() {
393 let cell
: &UnsafeCell
<[i32]> = &UnsafeCell
::new([1, 2, 3]);
395 let val
: &mut [i32] = unsafe { &mut *cell.get() }
;
399 let comp
: &mut [i32] = &mut [4, 2, 5];
400 assert_eq
!(unsafe { &mut *cell.get() }
, comp
);
404 fn refcell_unsized() {
405 let cell
: &RefCell
<[i32]> = &RefCell
::new([1, 2, 3]);
407 let b
= &mut *cell
.borrow_mut();
411 let comp
: &mut [i32] = &mut [4, 2, 5];
412 assert_eq
!(&*cell
.borrow(), comp
);
416 fn refcell_ref_coercion() {
417 let cell
: RefCell
<[i32; 3]> = RefCell
::new([1, 2, 3]);
419 let mut cellref
: RefMut
<'_
, [i32; 3]> = cell
.borrow_mut();
421 let mut coerced
: RefMut
<'_
, [i32]> = cellref
;
425 let comp
: &mut [i32] = &mut [4, 2, 5];
426 let cellref
: Ref
<'_
, [i32; 3]> = cell
.borrow();
427 assert_eq
!(&*cellref
, comp
);
428 let coerced
: Ref
<'_
, [i32]> = cellref
;
429 assert_eq
!(&*coerced
, comp
);
435 fn refcell_swap_borrows() {
436 let x
= RefCell
::new(0);
438 let y
= RefCell
::new(1);
444 fn refcell_replace_borrows() {
445 let x
= RefCell
::new(0);
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());
460 const UNSAFE_CELL
: UnsafeCell
<i32> = UnsafeCell
::new(3);
461 const _
: i32 = UNSAFE_CELL
.into_inner();
463 const REF_CELL
: RefCell
<i32> = RefCell
::new(3);
464 const _
: i32 = REF_CELL
.into_inner();
466 const CELL
: Cell
<i32> = Cell
::new(3);
467 const _
: i32 = CELL
.into_inner();
469 const UNSAFE_CELL_FROM
: UnsafeCell
<i32> = UnsafeCell
::from(3);
470 const _
: i32 = UNSAFE_CELL
.into_inner();
472 const REF_CELL_FROM
: RefCell
<i32> = RefCell
::from(3);
473 const _
: i32 = REF_CELL
.into_inner();
475 const CELL_FROM
: Cell
<i32> = Cell
::from(3);
476 const _
: i32 = CELL
.into_inner();