diff options
| author | Michal 'vorner' Vaner <vorner@vorner.cz> | 2020-04-13 17:17:34 +0200 |
|---|---|---|
| committer | Michal 'vorner' Vaner <vorner@vorner.cz> | 2020-04-13 17:17:34 +0200 |
| commit | 80ccddc0ed8627c0fc5e15c7526f2702ce64adb9 (patch) | |
| tree | 959ba36bf6ddcc256d0888f4acdc01de94399749 /src/liballoc | |
| parent | 4d1fbaccb822b6d52dc786589de7918d3c5effb1 (diff) | |
| download | rust-80ccddc0ed8627c0fc5e15c7526f2702ce64adb9.tar.gz rust-80ccddc0ed8627c0fc5e15c7526f2702ce64adb9.zip | |
weak-into-raw: as_raw -> as_ptr + dangling garbage
* Rename Weak::as_raw to Weak::as_ptr for consistency with some other types. * The as_ptr for a dangling Weak pointer might return whatever garbage (and takes that advantage to avoid a conditional). * Don't guarantee to be able to do `Weak::from_raw(weak.as_ptr())` (even though it'll still work fine).
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/rc.rs | 41 | ||||
| -rw-r--r-- | src/liballoc/sync.rs | 41 |
2 files changed, 30 insertions, 52 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index abc4056cf56..59424de4277 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1644,8 +1644,8 @@ impl<T> Weak<T> { /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`. /// - /// The pointer is valid only if there are some strong references. The pointer may be dangling - /// or even [`null`] otherwise. + /// The pointer is valid only if there are some strong references. The pointer may be dangling, + /// unaligned or even [`null`] otherwise. /// /// # Examples /// @@ -1658,31 +1658,22 @@ impl<T> Weak<T> { /// 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())); + /// assert!(ptr::eq(&*strong, weak.as_ptr())); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*weak.as_raw() }); + /// assert_eq!("hello", unsafe { &*weak.as_ptr() }); /// /// drop(strong); - /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to + /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!("hello", unsafe { &*weak.as_raw() }); + /// // assert_eq!("hello", unsafe { &*weak.as_ptr() }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn as_raw(&self) -> *const T { - match self.inner() { - None => ptr::null(), - Some(inner) => { - let offset = data_offset_sized::<T>(); - let ptr = inner as *const RcBox<T>; - // Note: while the pointer we create may already point to dropped value, the - // allocation still lives (it must hold the weak point as long as we are alive). - // Therefore, the offset is OK to do, it won't get out of the allocation. - let ptr = unsafe { (ptr as *const u8).offset(offset) }; - ptr as *const T - } - } + pub fn as_ptr(&self) -> *const T { + let offset = data_offset_sized::<T>(); + let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset); + ptr as *const T } /// Consumes the `Weak<T>` and turns it into a raw pointer. @@ -1691,7 +1682,7 @@ impl<T> Weak<T> { /// can be turned back into the `Weak<T>` with [`from_raw`]. /// /// The same restrictions of accessing the target of the pointer as with - /// [`as_raw`] apply. + /// [`as_ptr`] apply. /// /// # Examples /// @@ -1712,10 +1703,10 @@ impl<T> Weak<T> { /// ``` /// /// [`from_raw`]: struct.Weak.html#method.from_raw - /// [`as_raw`]: struct.Weak.html#method.as_raw + /// [`as_ptr`]: struct.Weak.html#method.as_ptr #[unstable(feature = "weak_into_raw", issue = "60728")] pub fn into_raw(self) -> *const T { - let result = self.as_raw(); + let result = self.as_ptr(); mem::forget(self); result } @@ -1730,9 +1721,8 @@ impl<T> Weak<T> { /// /// # Safety /// - /// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was - /// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference - /// count. + /// The pointer must have originated from the [`into_raw`] and must still own its potential + /// weak reference count. /// /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count /// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created @@ -1765,7 +1755,6 @@ impl<T> Weak<T> { /// [`upgrade`]: struct.Weak.html#method.upgrade /// [`Rc`]: struct.Rc.html /// [`Weak`]: struct.Weak.html - /// [`as_raw`]: struct.Weak.html#method.as_raw /// [`new`]: struct.Weak.html#method.new /// [`forget`]: ../../std/mem/fn.forget.html #[unstable(feature = "weak_into_raw", issue = "60728")] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index b1b22e46a7c..203b386ba1d 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1340,8 +1340,8 @@ impl<T> Weak<T> { /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`. /// - /// The pointer is valid only if there are some strong references. The pointer may be dangling - /// or even [`null`] otherwise. + /// The pointer is valid only if there are some strong references. The pointer may be dangling, + /// unaligned or even [`null`] otherwise. /// /// # Examples /// @@ -1354,31 +1354,22 @@ impl<T> Weak<T> { /// 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())); + /// assert!(ptr::eq(&*strong, weak.as_ptr())); /// // The strong here keeps it alive, so we can still access the object. - /// assert_eq!("hello", unsafe { &*weak.as_raw() }); + /// assert_eq!("hello", unsafe { &*weak.as_ptr() }); /// /// drop(strong); - /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to + /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to /// // undefined behaviour. - /// // assert_eq!("hello", unsafe { &*weak.as_raw() }); + /// // assert_eq!("hello", unsafe { &*weak.as_ptr() }); /// ``` /// /// [`null`]: ../../std/ptr/fn.null.html #[unstable(feature = "weak_into_raw", issue = "60728")] - pub fn as_raw(&self) -> *const T { - match self.inner() { - None => ptr::null(), - Some(inner) => { - let offset = data_offset_sized::<T>(); - let ptr = inner as *const ArcInner<T>; - // Note: while the pointer we create may already point to dropped value, the - // allocation still lives (it must hold the weak point as long as we are alive). - // Therefore, the offset is OK to do, it won't get out of the allocation. - let ptr = unsafe { (ptr as *const u8).offset(offset) }; - ptr as *const T - } - } + pub fn as_ptr(&self) -> *const T { + let offset = data_offset_sized::<T>(); + let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset); + ptr as *const T } /// Consumes the `Weak<T>` and turns it into a raw pointer. @@ -1387,7 +1378,7 @@ impl<T> Weak<T> { /// can be turned back into the `Weak<T>` with [`from_raw`]. /// /// The same restrictions of accessing the target of the pointer as with - /// [`as_raw`] apply. + /// [`as_ptr`] apply. /// /// # Examples /// @@ -1408,10 +1399,10 @@ impl<T> Weak<T> { /// ``` /// /// [`from_raw`]: struct.Weak.html#method.from_raw - /// [`as_raw`]: struct.Weak.html#method.as_raw + /// [`as_ptr`]: struct.Weak.html#method.as_ptr #[unstable(feature = "weak_into_raw", issue = "60728")] pub fn into_raw(self) -> *const T { - let result = self.as_raw(); + let result = self.as_ptr(); mem::forget(self); result } @@ -1427,9 +1418,8 @@ impl<T> Weak<T> { /// /// # Safety /// - /// The pointer must have originated from the [`into_raw`] (or [`as_raw'], provided there was - /// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference - /// count. + /// The pointer must have originated from the [`into_raw`] and must still own its potential + /// weak reference count. /// /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count /// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created @@ -1458,7 +1448,6 @@ impl<T> Weak<T> { /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none()); /// ``` /// - /// [`as_raw`]: struct.Weak.html#method.as_raw /// [`new`]: struct.Weak.html#method.new /// [`into_raw`]: struct.Weak.html#method.into_raw /// [`upgrade`]: struct.Weak.html#method.upgrade |
