4 use std::cell::RefCell;
6 use std::convert::{From, TryInto};
8 use std::option::Option::{self, None, Some};
9 use std::result::Result::{Err, Ok};
13 let x = Rc::new(RefCell::new(5));
16 assert_eq!(*y.borrow(), 20);
26 fn test_simple_clone() {
34 fn test_destructor() {
35 let x: Rc<Box<_>> = Rc::new(Box::new(5));
42 let y = Rc::downgrade(&x);
43 assert!(y.upgrade().is_some());
49 let y = Rc::downgrade(&x);
51 assert!(y.upgrade().is_none());
55 fn weak_self_cyclic() {
57 x: RefCell<Option<Weak<Cycle>>>,
60 let a = Rc::new(Cycle { x: RefCell::new(None) });
61 let b = Rc::downgrade(&a.clone());
62 *a.x.borrow_mut() = Some(b);
64 // hopefully we don't double-free (or leak)...
70 assert!(Rc::is_unique(&x));
72 assert!(!Rc::is_unique(&x));
74 assert!(Rc::is_unique(&x));
75 let w = Rc::downgrade(&x);
76 assert!(!Rc::is_unique(&x));
78 assert!(Rc::is_unique(&x));
82 fn test_strong_count() {
84 assert!(Rc::strong_count(&a) == 1);
85 let w = Rc::downgrade(&a);
86 assert!(Rc::strong_count(&a) == 1);
87 let b = w.upgrade().expect("upgrade of live rc failed");
88 assert!(Rc::strong_count(&b) == 2);
89 assert!(Rc::strong_count(&a) == 2);
92 assert!(Rc::strong_count(&b) == 1);
94 assert!(Rc::strong_count(&b) == 2);
95 assert!(Rc::strong_count(&c) == 2);
99 fn test_weak_count() {
101 assert!(Rc::strong_count(&a) == 1);
102 assert!(Rc::weak_count(&a) == 0);
103 let w = Rc::downgrade(&a);
104 assert!(Rc::strong_count(&a) == 1);
105 assert!(Rc::weak_count(&a) == 1);
107 assert!(Rc::strong_count(&a) == 1);
108 assert!(Rc::weak_count(&a) == 0);
110 assert!(Rc::strong_count(&a) == 2);
111 assert!(Rc::weak_count(&a) == 0);
117 assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
118 assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
121 let w = Rc::downgrade(&a);
122 assert_eq!(Weak::strong_count(&w), 1);
123 assert_eq!(Weak::weak_count(&w), 1);
125 assert_eq!(Weak::strong_count(&w), 1);
126 assert_eq!(Weak::weak_count(&w), 2);
127 assert_eq!(Weak::strong_count(&w2), 1);
128 assert_eq!(Weak::weak_count(&w2), 2);
130 assert_eq!(Weak::strong_count(&w2), 1);
131 assert_eq!(Weak::weak_count(&w2), 1);
133 assert_eq!(Weak::strong_count(&w2), 2);
134 assert_eq!(Weak::weak_count(&w2), 1);
137 assert_eq!(Weak::strong_count(&w2), 0);
138 assert_eq!(Weak::weak_count(&w2), 0);
145 assert_eq!(Rc::try_unwrap(x), Ok(3));
148 assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
150 let _w = Rc::downgrade(&x);
151 assert_eq!(Rc::try_unwrap(x), Ok(5));
156 let x = Rc::new(Box::new("hello"));
159 let x_ptr = Rc::into_raw(x);
162 assert_eq!(**x_ptr, "hello");
164 let x = Rc::from_raw(x_ptr);
165 assert_eq!(**x, "hello");
167 assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
172 fn test_into_from_raw_unsized() {
173 use std::fmt::Display;
174 use std::string::ToString;
176 let rc: Rc<str> = Rc::from("foo");
178 let ptr = Rc::into_raw(rc.clone());
179 let rc2 = unsafe { Rc::from_raw(ptr) };
181 assert_eq!(unsafe { &*ptr }, "foo");
184 let rc: Rc<dyn Display> = Rc::new(123);
186 let ptr = Rc::into_raw(rc.clone());
187 let rc2 = unsafe { Rc::from_raw(ptr) };
189 assert_eq!(unsafe { &*ptr }.to_string(), "123");
190 assert_eq!(rc2.to_string(), "123");
194 fn into_from_weak_raw() {
195 let x = Rc::new(Box::new("hello"));
196 let y = Rc::downgrade(&x);
198 let y_ptr = Weak::into_raw(y);
200 assert_eq!(**y_ptr, "hello");
202 let y = Weak::from_raw(y_ptr);
203 let y_up = Weak::upgrade(&y).unwrap();
204 assert_eq!(**y_up, "hello");
207 assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
212 fn test_into_from_weak_raw_unsized() {
213 use std::fmt::Display;
214 use std::string::ToString;
216 let arc: Rc<str> = Rc::from("foo");
217 let weak: Weak<str> = Rc::downgrade(&arc);
219 let ptr = Weak::into_raw(weak.clone());
220 let weak2 = unsafe { Weak::from_raw(ptr) };
222 assert_eq!(unsafe { &*ptr }, "foo");
223 assert!(weak.ptr_eq(&weak2));
225 let arc: Rc<dyn Display> = Rc::new(123);
226 let weak: Weak<dyn Display> = Rc::downgrade(&arc);
228 let ptr = Weak::into_raw(weak.clone());
229 let weak2 = unsafe { Weak::from_raw(ptr) };
231 assert_eq!(unsafe { &*ptr }.to_string(), "123");
232 assert!(weak.ptr_eq(&weak2));
237 let mut x = Rc::new(3);
238 *Rc::get_mut(&mut x).unwrap() = 4;
241 assert!(Rc::get_mut(&mut x).is_none());
243 assert!(Rc::get_mut(&mut x).is_some());
244 let _w = Rc::downgrade(&x);
245 assert!(Rc::get_mut(&mut x).is_none());
249 fn test_cowrc_clone_make_unique() {
250 let mut cow0 = Rc::new(75);
251 let mut cow1 = cow0.clone();
252 let mut cow2 = cow1.clone();
254 assert!(75 == *Rc::make_mut(&mut cow0));
255 assert!(75 == *Rc::make_mut(&mut cow1));
256 assert!(75 == *Rc::make_mut(&mut cow2));
258 *Rc::make_mut(&mut cow0) += 1;
259 *Rc::make_mut(&mut cow1) += 2;
260 *Rc::make_mut(&mut cow2) += 3;
262 assert!(76 == *cow0);
263 assert!(77 == *cow1);
264 assert!(78 == *cow2);
266 // none should point to the same backing memory
267 assert!(*cow0 != *cow1);
268 assert!(*cow0 != *cow2);
269 assert!(*cow1 != *cow2);
273 fn test_cowrc_clone_unique2() {
274 let mut cow0 = Rc::new(75);
275 let cow1 = cow0.clone();
276 let cow2 = cow1.clone();
278 assert!(75 == *cow0);
279 assert!(75 == *cow1);
280 assert!(75 == *cow2);
282 *Rc::make_mut(&mut cow0) += 1;
284 assert!(76 == *cow0);
285 assert!(75 == *cow1);
286 assert!(75 == *cow2);
288 // cow1 and cow2 should share the same contents
289 // cow0 should have a unique reference
290 assert!(*cow0 != *cow1);
291 assert!(*cow0 != *cow2);
292 assert!(*cow1 == *cow2);
296 fn test_cowrc_clone_weak() {
297 let mut cow0 = Rc::new(75);
298 let cow1_weak = Rc::downgrade(&cow0);
300 assert!(75 == *cow0);
301 assert!(75 == *cow1_weak.upgrade().unwrap());
303 *Rc::make_mut(&mut cow0) += 1;
305 assert!(76 == *cow0);
306 assert!(cow1_weak.upgrade().is_none());
311 let foo = Rc::new(75);
312 assert_eq!(format!("{foo:?}"), "75");
317 let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
318 assert_eq!(foo, foo.clone());
322 fn test_maybe_thin_unsized() {
323 // If/when custom thin DSTs exist, this test should be updated to use one
324 use std::ffi::{CStr, CString};
326 let x: Rc<CStr> = Rc::from(CString::new("swordfish").unwrap().into_boxed_c_str());
327 assert_eq!(format!("{x:?}"), "\"swordfish\"");
328 let y: Weak<CStr> = Rc::downgrade(&x);
331 // At this point, the weak points to a dropped DST
332 assert!(y.upgrade().is_none());
333 // But we still need to be able to get the alloc layout to drop.
334 // CStr has no drop glue, but custom DSTs might, and need to work.
339 fn test_from_owned() {
341 let foo_rc = Rc::from(foo);
342 assert!(123 == *foo_rc);
347 let foo: Weak<usize> = Weak::new();
348 assert!(foo.upgrade().is_none());
353 let five = Rc::new(5);
354 let same_five = five.clone();
355 let other_five = Rc::new(5);
357 assert!(Rc::ptr_eq(&five, &same_five));
358 assert!(!Rc::ptr_eq(&five, &other_five));
363 let r: Rc<str> = Rc::from("foo");
365 assert_eq!(&r[..], "foo");
369 fn test_copy_from_slice() {
370 let s: &[u32] = &[1, 2, 3];
371 let r: Rc<[u32]> = Rc::from(s);
373 assert_eq!(&r[..], [1, 2, 3]);
377 fn test_clone_from_slice() {
378 #[derive(Clone, Debug, Eq, PartialEq)]
381 let s: &[X] = &[X(1), X(2), X(3)];
382 let r: Rc<[X]> = Rc::from(s);
384 assert_eq!(&r[..], s);
389 fn test_clone_from_slice_panic() {
390 use std::string::{String, ToString};
392 struct Fail(u32, String);
394 impl Clone for Fail {
395 fn clone(&self) -> Fail {
399 Fail(self.0, self.1.clone())
404 &[Fail(0, "foo".to_string()), Fail(1, "bar".to_string()), Fail(2, "baz".to_string())];
406 // Should panic, but not cause memory corruption
407 let _r: Rc<[Fail]> = Rc::from(s);
412 let b: Box<u32> = Box::new(123);
413 let r: Rc<u32> = Rc::from(b);
419 fn test_from_box_str() {
420 use std::string::String;
422 let s = String::from("foo").into_boxed_str();
423 let r: Rc<str> = Rc::from(s);
425 assert_eq!(&r[..], "foo");
429 fn test_from_box_slice() {
430 let s = vec![1, 2, 3].into_boxed_slice();
431 let r: Rc<[u32]> = Rc::from(s);
433 assert_eq!(&r[..], [1, 2, 3]);
437 fn test_from_box_trait() {
438 use std::fmt::Display;
439 use std::string::ToString;
441 let b: Box<dyn Display> = Box::new(123);
442 let r: Rc<dyn Display> = Rc::from(b);
444 assert_eq!(r.to_string(), "123");
448 fn test_from_box_trait_zero_sized() {
451 let b: Box<dyn Debug> = Box::new(());
452 let r: Rc<dyn Debug> = Rc::from(b);
454 assert_eq!(format!("{r:?}"), "()");
459 let v = vec![1, 2, 3];
460 let r: Rc<[u32]> = Rc::from(v);
462 assert_eq!(&r[..], [1, 2, 3]);
469 let r1: Rc<dyn Any> = Rc::new(i32::MAX);
470 let r2: Rc<dyn Any> = Rc::new("abc");
472 assert!(r1.clone().downcast::<u32>().is_err());
474 let r1i32 = r1.downcast::<i32>();
475 assert!(r1i32.is_ok());
476 assert_eq!(r1i32.unwrap(), Rc::new(i32::MAX));
478 assert!(r2.clone().downcast::<i32>().is_err());
480 let r2str = r2.downcast::<&'static str>();
481 assert!(r2str.is_ok());
482 assert_eq!(r2str.unwrap(), Rc::new("abc"));
486 fn test_array_from_slice() {
487 let v = vec![1, 2, 3];
488 let r: Rc<[u32]> = Rc::from(v);
490 let a: Result<Rc<[u32; 3]>, _> = r.clone().try_into();
493 let a: Result<Rc<[u32; 2]>, _> = r.clone().try_into();
498 fn test_rc_cyclic_with_zero_refs() {
500 inner: Weak<ZeroRefs>,
503 let zero_refs = Rc::new_cyclic(|inner| {
504 assert_eq!(inner.strong_count(), 0);
505 assert!(inner.upgrade().is_none());
506 ZeroRefs { inner: Weak::new() }
509 assert_eq!(Rc::strong_count(&zero_refs), 1);
510 assert_eq!(Rc::weak_count(&zero_refs), 0);
511 assert_eq!(zero_refs.inner.strong_count(), 0);
512 assert_eq!(zero_refs.inner.weak_count(), 0);
516 fn test_rc_cyclic_with_one_ref() {
521 let one_ref = Rc::new_cyclic(|inner| {
522 assert_eq!(inner.strong_count(), 0);
523 assert!(inner.upgrade().is_none());
524 OneRef { inner: inner.clone() }
527 assert_eq!(Rc::strong_count(&one_ref), 1);
528 assert_eq!(Rc::weak_count(&one_ref), 1);
530 let one_ref2 = Weak::upgrade(&one_ref.inner).unwrap();
531 assert!(Rc::ptr_eq(&one_ref, &one_ref2));
533 assert_eq!(one_ref.inner.strong_count(), 2);
534 assert_eq!(one_ref.inner.weak_count(), 1);
538 fn test_rc_cyclic_with_two_ref() {
540 inner: Weak<TwoRefs>,
541 inner1: Weak<TwoRefs>,
544 let two_refs = Rc::new_cyclic(|inner| {
545 assert_eq!(inner.strong_count(), 0);
546 assert!(inner.upgrade().is_none());
547 TwoRefs { inner: inner.clone(), inner1: inner.clone() }
550 assert_eq!(Rc::strong_count(&two_refs), 1);
551 assert_eq!(Rc::weak_count(&two_refs), 2);
553 let two_ref3 = Weak::upgrade(&two_refs.inner).unwrap();
554 assert!(Rc::ptr_eq(&two_refs, &two_ref3));
556 let two_ref2 = Weak::upgrade(&two_refs.inner1).unwrap();
557 assert!(Rc::ptr_eq(&two_refs, &two_ref2));
559 assert_eq!(Rc::strong_count(&two_refs), 3);
560 assert_eq!(Rc::weak_count(&two_refs), 2);