diff --git a/rust-version b/rust-version index 7695b06943..d93fb8b695 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -4b9d80325a65b0375eea526409a0f3aaf1cbc23c +81970852e172c04322cbf8ba23effabeb491c83c diff --git a/tests/compile-fail/rc_as_raw.rs b/tests/compile-fail/rc_as_raw.rs new file mode 100644 index 0000000000..3e6e96456f --- /dev/null +++ b/tests/compile-fail/rc_as_raw.rs @@ -0,0 +1,19 @@ +#![feature(weak_into_raw)] + +use std::rc::{Rc, Weak}; +use std::ptr; + +/// Taken from the `Weak::as_raw` doctest. +fn main() { + let strong = Rc::new(Box::new(42)); + let weak = Rc::downgrade(&strong); + // Both point to the same object + assert!(ptr::eq(&*strong, Weak::as_raw(&weak))); + // The strong here keeps it alive, so we can still access the object. + assert_eq!(42, **unsafe { &*Weak::as_raw(&weak) }); + + drop(strong); + // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to + // undefined behaviour. + assert_eq!(42, **unsafe { &*Weak::as_raw(&weak) }); //~ ERROR dangling pointer +} diff --git a/tests/run-pass/rc.rs b/tests/run-pass/rc.rs index 164842ab4d..9b4d51ed37 100644 --- a/tests/run-pass/rc.rs +++ b/tests/run-pass/rc.rs @@ -1,5 +1,7 @@ +#![feature(weak_into_raw)] + use std::cell::{Cell, RefCell}; -use std::rc::Rc; +use std::rc::{Rc, Weak}; use std::sync::Arc; use std::fmt::Debug; @@ -69,6 +71,37 @@ fn rc_fat_ptr_eq() { drop(unsafe { Rc::from_raw(r) }); } +/// 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)); +} + +/// 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()); +} + fn main() { rc_fat_ptr_eq(); rc_refcell(); @@ -76,5 +109,8 @@ fn main() { rc_cell(); rc_raw(); rc_from(); + weak_into_raw(); + weak_from_raw(); + arc(); }