2 use core
::default::Default
;
8 assert_eq
!(x
, Cell
::new(10));
9 assert_eq
!(x
.get(), 10);
11 assert_eq
!(x
, Cell
::new(20));
12 assert_eq
!(x
.get(), 20);
14 let y
= Cell
::new((30, 40));
15 assert_eq
!(y
, Cell
::new((30, 40)));
16 assert_eq
!(y
.get(), (30, 40));
21 let x
= Cell
::new(10);
23 assert_eq
!(x
.update(|x
| x
+ 5), 15);
24 assert_eq
!(x
.get(), 15);
26 assert_eq
!(x
.update(|x
| x
/ 3), 5);
27 assert_eq
!(x
.get(), 5);
31 fn cell_has_sensible_show() {
32 let x
= Cell
::new("foo bar");
33 assert
!(format
!("{:?}", x
).contains(x
.get()));
36 assert
!(format
!("{:?}", x
).contains(x
.get()));
40 fn ref_and_refmut_have_sensible_show() {
41 let refcell
= RefCell
::new("foo");
43 let refcell_refmut
= refcell
.borrow_mut();
44 assert
!(format
!("{:?}", refcell_refmut
).contains("foo"));
47 let refcell_ref
= refcell
.borrow();
48 assert
!(format
!("{:?}", refcell_ref
).contains("foo"));
53 fn double_imm_borrow() {
54 let x
= RefCell
::new(0);
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());
67 fn no_imm_then_borrow_mut() {
68 let x
= RefCell
::new(0);
70 assert
!(x
.try_borrow_mut().is_err());
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());
82 fn imm_release_borrow_mut() {
83 let x
= RefCell
::new(0);
91 fn mut_release_borrow_mut() {
92 let x
= RefCell
::new(0);
94 let _b1
= x
.borrow_mut();
100 fn double_borrow_single_release_no_borrow_mut() {
101 let x
= RefCell
::new(0);
102 let _b1
= x
.borrow();
104 let _b2
= x
.borrow();
106 assert
!(x
.try_borrow().is_ok());
107 assert
!(x
.try_borrow_mut().is_err());
112 fn discard_doesnt_unborrow() {
113 let x
= RefCell
::new(0);
116 let _b
= x
.borrow_mut();
120 fn ref_clone_updates_flag() {
121 let x
= RefCell
::new(0);
124 assert
!(x
.try_borrow().is_ok());
125 assert
!(x
.try_borrow_mut().is_err());
127 let _b2
= Ref
::clone(&b1
);
128 assert
!(x
.try_borrow().is_ok());
129 assert
!(x
.try_borrow_mut().is_err());
131 assert
!(x
.try_borrow().is_ok());
132 assert
!(x
.try_borrow_mut().is_err());
134 assert
!(x
.try_borrow().is_ok());
135 assert
!(x
.try_borrow_mut().is_ok());
139 fn ref_map_does_not_update_flag() {
140 let x
= RefCell
::new(Some(5));
142 let b1
: Ref
<'_
, Option
<u32>> = x
.borrow();
143 assert
!(x
.try_borrow().is_ok());
144 assert
!(x
.try_borrow_mut().is_err());
146 let b2
: Ref
<'_
, u32> = Ref
::map(b1
, |o
| o
.as_ref().unwrap());
148 assert
!(x
.try_borrow().is_ok());
149 assert
!(x
.try_borrow_mut().is_err());
151 assert
!(x
.try_borrow().is_ok());
152 assert
!(x
.try_borrow_mut().is_ok());
154 assert
!(x
.try_borrow().is_ok());
155 assert
!(x
.try_borrow_mut().is_ok());
159 fn ref_map_split_updates_flag() {
160 let x
= RefCell
::new([1, 2]);
163 assert
!(x
.try_borrow().is_ok());
164 assert
!(x
.try_borrow_mut().is_err());
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());
170 assert
!(x
.try_borrow().is_ok());
171 assert
!(x
.try_borrow_mut().is_ok());
173 assert
!(x
.try_borrow().is_ok());
174 assert
!(x
.try_borrow_mut().is_ok());
177 let b1
= x
.borrow_mut();
178 assert
!(x
.try_borrow().is_err());
179 assert
!(x
.try_borrow_mut().is_err());
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());
185 assert
!(x
.try_borrow().is_err());
186 assert
!(x
.try_borrow_mut().is_err());
188 assert
!(x
.try_borrow().is_ok());
189 assert
!(x
.try_borrow_mut().is_ok());
191 assert
!(x
.try_borrow().is_ok());
192 assert
!(x
.try_borrow_mut().is_ok());
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]);
204 fn ref_mut_map_split() {
205 let x
= RefCell
::new([1, 2]);
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]);
213 assert_eq
!(*x
.borrow(), [2, 1]);
217 fn ref_map_accessor() {
218 struct X(RefCell
<(u32, char)>);
220 fn accessor(&self) -> Ref
<'_
, u32> {
221 Ref
::map(self.0.borrow(), |tuple
| &tuple
.0)
224 let x
= X(RefCell
::new((7, 'z'
)));
225 let d
: Ref
<'_
, u32> = x
.accessor();
230 fn ref_mut_map_accessor() {
231 struct X(RefCell
<(u32, char)>);
233 fn accessor(&self) -> RefMut
<'_
, u32> {
234 RefMut
::map(self.0.borrow_mut(), |tuple
| &mut tuple
.0)
237 let x
= X(RefCell
::new((7, 'z'
)));
239 let mut d
: RefMut
<'_
, u32> = x
.accessor();
243 assert_eq
!(*x
.0.borrow(), (8, 'z'
));
248 let c1
: Cell
<usize> = Cell
::new(0);
250 assert_eq
!(1, unsafe { *c1.as_ptr() }
);
252 let c2
: Cell
<usize> = Cell
::new(0);
256 assert_eq
!(1, c2
.get());
258 let r1
: RefCell
<usize> = RefCell
::new(0);
259 *r1
.borrow_mut() = 1;
260 assert_eq
!(1, unsafe { *r1.as_ptr() }
);
262 let r2
: RefCell
<usize> = RefCell
::new(0);
266 assert_eq
!(1, *r2
.borrow());
271 let cell
: Cell
<u32> = Default
::default();
272 assert_eq
!(0, cell
.get());
277 let cell
= Cell
::new(10);
279 assert_eq
!(20, cell
.get());
281 let cell
= Cell
::new("Hello".to_owned());
282 cell
.set("World".to_owned());
283 assert_eq
!("World".to_owned(), cell
.into_inner());
288 let cell
= Cell
::new(10);
289 assert_eq
!(10, cell
.replace(20));
290 assert_eq
!(20, cell
.get());
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());
298 fn cell_into_inner() {
299 let cell
= Cell
::new(10);
300 assert_eq
!(10, cell
.into_inner());
302 let cell
= Cell
::new("Hello world".to_owned());
303 assert_eq
!("Hello world".to_owned(), cell
.into_inner());
308 #[derive(Copy, Clone)]
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);
322 let a
= Point { x: 10, y: 11, z: 12 }
;
323 let b
= &Cell
::new(a
);
324 assert_eq
!(b
.get().z
, 12);
327 assert_eq
!(b
.get().z
, 13);
331 fn cell_does_not_clone() {
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.
348 let x
= Cell
::new(Foo { x: 22 }
);
354 fn refcell_default() {
355 let cell
: RefCell
<u64> = Default
::default();
356 assert_eq
!(0, *cell
.borrow());
360 fn unsafe_cell_unsized() {
361 let cell
: &UnsafeCell
<[i32]> = &UnsafeCell
::new([1, 2, 3]);
363 let val
: &mut [i32] = unsafe { &mut *cell.get() }
;
367 let comp
: &mut [i32] = &mut [4, 2, 5];
368 assert_eq
!(unsafe { &mut *cell.get() }
, comp
);
372 fn refcell_unsized() {
373 let cell
: &RefCell
<[i32]> = &RefCell
::new([1, 2, 3]);
375 let b
= &mut *cell
.borrow_mut();
379 let comp
: &mut [i32] = &mut [4, 2, 5];
380 assert_eq
!(&*cell
.borrow(), comp
);
384 fn refcell_ref_coercion() {
385 let cell
: RefCell
<[i32; 3]> = RefCell
::new([1, 2, 3]);
387 let mut cellref
: RefMut
<'_
, [i32; 3]> = cell
.borrow_mut();
389 let mut coerced
: RefMut
<'_
, [i32]> = cellref
;
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
);
403 fn refcell_swap_borrows() {
404 let x
= RefCell
::new(0);
406 let y
= RefCell
::new(1);
412 fn refcell_replace_borrows() {
413 let x
= RefCell
::new(0);
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());
428 const UNSAFE_CELL
: UnsafeCell
<i32> = UnsafeCell
::new(3);
429 const _
: i32 = UNSAFE_CELL
.into_inner();
431 const REF_CELL
: RefCell
<i32> = RefCell
::new(3);
432 const _
: i32 = REF_CELL
.into_inner();
434 const CELL
: Cell
<i32> = Cell
::new(3);
435 const _
: i32 = CELL
.into_inner();