rust/tests/run-pass/rc.rs

154 lines
3.7 KiB
Rust
Raw Normal View History

2022-04-01 13:10:24 -05:00
// compile-flags: -Zmiri-strict-provenance -Zmiri-check-number-validity
2019-08-18 04:31:18 -05:00
#![feature(new_uninit)]
#![feature(get_mut_unchecked)]
2019-05-29 12:35:47 -05:00
2018-11-08 01:58:03 -06:00
use std::cell::{Cell, RefCell};
2019-05-29 12:35:47 -05:00
use std::rc::{Rc, Weak};
use std::sync::{Arc, Weak as ArcWeak};
2019-02-08 09:27:00 -06:00
use std::fmt::Debug;
2017-08-29 09:51:26 -05:00
fn rc_refcell() {
let r = Rc::new(RefCell::new(42));
2018-11-08 01:58:03 -06:00
let r2 = r.clone();
*r.borrow_mut() += 10;
2018-11-08 01:58:03 -06:00
let x = *r2.borrow();
2017-08-29 09:51:26 -05:00
assert_eq!(x, 52);
}
2018-11-08 01:58:03 -06:00
fn rc_cell() {
let r = Rc::new(Cell::new(42));
let r2 = r.clone();
let x = r.get();
r2.set(x + x);
assert_eq!(r.get(), 84);
}
fn rc_refcell2() {
let r = Rc::new(RefCell::new(42));
let r2 = r.clone();
*r.borrow_mut() += 10;
let x = r2.borrow();
let r3 = r.clone();
let y = r3.borrow();
assert_eq!((*x + *y)/2, 52);
}
fn rc_raw() {
let r = Rc::new(0);
let r2 = Rc::into_raw(r.clone());
let r2 = unsafe { Rc::from_raw(r2) };
assert!(Rc::ptr_eq(&r, &r2));
drop(r);
assert!(Rc::try_unwrap(r2).is_ok());
}
2018-11-08 01:58:03 -06:00
fn arc() {
fn test() -> Arc<i32> {
let a = Arc::new(42);
a
}
assert_eq!(*test(), 42);
let raw = ArcWeak::into_raw(ArcWeak::<usize>::new());
drop(unsafe { ArcWeak::from_raw(raw) });
2018-11-08 01:58:03 -06:00
}
2017-08-29 09:51:26 -05:00
// Make sure this Rc doesn't fall apart when touched
fn check_unique_rc<T: ?Sized>(mut r: Rc<T>) {
let r2 = r.clone();
assert!(Rc::get_mut(&mut r).is_none());
drop(r2);
assert!(Rc::get_mut(&mut r).is_some());
}
fn rc_from() {
check_unique_rc::<[_]>(Rc::from(&[1,2,3] as &[_]));
check_unique_rc::<[_]>(Rc::from(vec![1,2,3]));
check_unique_rc::<[_]>(Rc::from(Box::new([1,2,3]) as Box<[_]>));
check_unique_rc::<str>(Rc::from("Hello, World!"));
}
2019-02-08 09:27:00 -06:00
fn rc_fat_ptr_eq() {
let p = Rc::new(1) as Rc<dyn Debug>;
let a: *const dyn Debug = &*p;
2019-02-08 09:27:00 -06:00
let r = Rc::into_raw(p);
2019-02-08 16:48:37 -06:00
assert!(a == r);
2019-02-08 09:27:00 -06:00
drop(unsafe { Rc::from_raw(r) });
}
2019-05-29 12:35:47 -05:00
/// Taken from the `Weak::into_raw` doctest.
fn weak_into_raw() {
let strong = Rc::new(42);
let weak = Rc::downgrade(&strong);
let raw = Weak::into_raw(weak);
assert_eq!(1, Rc::weak_count(&strong));
assert_eq!(42, unsafe { *raw });
drop(unsafe { Weak::from_raw(raw) });
assert_eq!(0, Rc::weak_count(&strong));
let raw = Weak::into_raw(Weak::<usize>::new());
drop(unsafe { Weak::from_raw(raw) });
2019-05-29 12:35:47 -05:00
}
/// Taken from the `Weak::from_raw` doctest.
fn weak_from_raw() {
let strong = Rc::new(42);
let raw_1 = Weak::into_raw(Rc::downgrade(&strong));
let raw_2 = Weak::into_raw(Rc::downgrade(&strong));
assert_eq!(2, Rc::weak_count(&strong));
assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
assert_eq!(1, Rc::weak_count(&strong));
drop(strong);
// Decrement the last weak count.
assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none());
}
2019-08-18 04:31:18 -05:00
fn rc_uninit() {
let mut five = Rc::<Box<u32>>::new_uninit();
let five = unsafe {
// Deferred initialization:
Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(Box::new(5));
five.assume_init()
};
assert_eq!(**five, 5)
}
fn rc_uninit_slice() {
let mut values = Rc::<[Box<usize>]>::new_uninit_slice(3);
let values = unsafe {
// Deferred initialization:
Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(Box::new(0));
Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(Box::new(1));
Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(Box::new(2));
values.assume_init()
};
for (idx, i) in values.iter().enumerate() {
assert_eq!(idx, **i);
}
}
fn main() {
2019-02-08 09:27:00 -06:00
rc_fat_ptr_eq();
rc_refcell();
2018-11-08 01:58:03 -06:00
rc_refcell2();
rc_cell();
rc_raw();
2017-08-29 09:51:26 -05:00
rc_from();
2019-05-29 12:35:47 -05:00
weak_into_raw();
weak_from_raw();
2019-08-18 04:31:18 -05:00
rc_uninit();
rc_uninit_slice();
2019-05-29 12:35:47 -05:00
2018-11-08 01:58:03 -06:00
arc();
}