From 764d163099c6b5299efe7551de1180603f0c8367 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sat, 1 Jun 2019 11:55:25 +0200 Subject: [PATCH 1/2] docs: Use String in Rc::into_raw examples It is unclear if accessing an integer after `drop_in_place` has been called on it is undefined behaviour or not, as demonstrated by the discussion in https://github.com/rust-lang/rust/pull/60766#pullrequestreview-243414222. Avoid these uncertainties by using String which frees memory in its `drop_in_place` to make sure this is undefined behaviour. The message in the docs should be to watch out and not access the data after that, not discussing when one maybe could get away with it O:-). --- src/liballoc/rc.rs | 14 +++++++------- src/liballoc/sync.rs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1f357a719bb43..b3b67a80e1063 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1274,17 +1274,17 @@ impl Weak { /// use std::rc::{Rc, Weak}; /// use std::ptr; /// - /// let strong = Rc::new(42); + /// let strong = Rc::new("hello".to_owned()); /// 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) }); + /// assert_eq!("hello", 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) }); + /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html @@ -1319,12 +1319,12 @@ impl Weak { /// /// use std::rc::{Rc, Weak}; /// - /// let strong = Rc::new(42); + /// let strong = Rc::new("hello".to_owned()); /// let weak = Rc::downgrade(&strong); /// let raw = Weak::into_raw(weak); /// /// assert_eq!(1, Rc::weak_count(&strong)); - /// assert_eq!(42, unsafe { *raw }); + /// assert_eq!("hello", unsafe { &*raw }); /// /// drop(unsafe { Weak::from_raw(raw) }); /// assert_eq!(0, Rc::weak_count(&strong)); @@ -1360,14 +1360,14 @@ impl Weak { /// /// use std::rc::{Rc, Weak}; /// - /// let strong = Rc::new(42); + /// let strong = Rc::new("hello".to_owned()); /// /// 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!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); /// assert_eq!(1, Rc::weak_count(&strong)); /// /// drop(strong); diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 70865656c510e..38f2d1a14dcee 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1083,17 +1083,17 @@ impl Weak { /// use std::sync::{Arc, Weak}; /// use std::ptr; /// - /// let strong = Arc::new(42); + /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::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) }); + /// assert_eq!("hello", 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) }); + /// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html @@ -1128,12 +1128,12 @@ impl Weak { /// /// use std::sync::{Arc, Weak}; /// - /// let strong = Arc::new(42); + /// let strong = Arc::new("hello".to_owned()); /// let weak = Arc::downgrade(&strong); /// let raw = Weak::into_raw(weak); /// /// assert_eq!(1, Arc::weak_count(&strong)); - /// assert_eq!(42, unsafe { *raw }); + /// assert_eq!("hello", unsafe { &*raw }); /// /// drop(unsafe { Weak::from_raw(raw) }); /// assert_eq!(0, Arc::weak_count(&strong)); @@ -1170,14 +1170,14 @@ impl Weak { /// /// use std::sync::{Arc, Weak}; /// - /// let strong = Arc::new(42); + /// let strong = Arc::new("hello".to_owned()); /// /// let raw_1 = Weak::into_raw(Arc::downgrade(&strong)); /// let raw_2 = Weak::into_raw(Arc::downgrade(&strong)); /// /// assert_eq!(2, Arc::weak_count(&strong)); /// - /// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); + /// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap()); /// assert_eq!(1, Arc::weak_count(&strong)); /// /// drop(strong); From e5af0e51ab1e436fda8f8a45115114a46deebf0d Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Wed, 12 Jun 2019 21:35:37 +0200 Subject: [PATCH 2/2] fixup! docs: Use String in Rc::into_raw examples --- src/liballoc/rc.rs | 14 +++++++------- src/liballoc/sync.rs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index b3b67a80e1063..df2bd2bc9397a 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -375,9 +375,9 @@ impl Rc { /// ``` /// use std::rc::Rc; /// - /// let x = Rc::new(10); + /// let x = Rc::new("hello".to_owned()); /// let x_ptr = Rc::into_raw(x); - /// assert_eq!(unsafe { *x_ptr }, 10); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { @@ -401,13 +401,13 @@ impl Rc { /// ``` /// use std::rc::Rc; /// - /// let x = Rc::new(10); + /// let x = Rc::new("hello".to_owned()); /// let x_ptr = Rc::into_raw(x); /// /// unsafe { /// // Convert back to an `Rc` to prevent leak. /// let x = Rc::from_raw(x_ptr); - /// assert_eq!(*x, 10); + /// assert_eq!(&*x, "hello"); /// /// // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe. /// } @@ -437,10 +437,10 @@ impl Rc { /// /// use std::rc::Rc; /// - /// let x = Rc::new(10); + /// let x = Rc::new("hello".to_owned()); /// let ptr = Rc::into_raw_non_null(x); - /// let deref = unsafe { *ptr.as_ref() }; - /// assert_eq!(deref, 10); + /// let deref = unsafe { ptr.as_ref() }; + /// assert_eq!(deref, "hello"); /// ``` #[unstable(feature = "rc_into_raw_non_null", issue = "47336")] #[inline] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 38f2d1a14dcee..2503f696bf329 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -356,9 +356,9 @@ impl Arc { /// ``` /// use std::sync::Arc; /// - /// let x = Arc::new(10); + /// let x = Arc::new("hello".to_owned()); /// let x_ptr = Arc::into_raw(x); - /// assert_eq!(unsafe { *x_ptr }, 10); + /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { @@ -382,13 +382,13 @@ impl Arc { /// ``` /// use std::sync::Arc; /// - /// let x = Arc::new(10); + /// let x = Arc::new("hello".to_owned()); /// let x_ptr = Arc::into_raw(x); /// /// unsafe { /// // Convert back to an `Arc` to prevent leak. /// let x = Arc::from_raw(x_ptr); - /// assert_eq!(*x, 10); + /// assert_eq!(&*x, "hello"); /// /// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe. /// } @@ -418,10 +418,10 @@ impl Arc { /// /// use std::sync::Arc; /// - /// let x = Arc::new(10); + /// let x = Arc::new("hello".to_owned()); /// let ptr = Arc::into_raw_non_null(x); - /// let deref = unsafe { *ptr.as_ref() }; - /// assert_eq!(deref, 10); + /// let deref = unsafe { ptr.as_ref() }; + /// assert_eq!(deref, "hello"); /// ``` #[unstable(feature = "rc_into_raw_non_null", issue = "47336")] #[inline]