diff --git a/compiler/rustc_data_structures/src/owning_ref/mod.rs b/compiler/rustc_data_structures/src/owning_ref/mod.rs index d1d92b905b82e..be57c150b1996 100644 --- a/compiler/rustc_data_structures/src/owning_ref/mod.rs +++ b/compiler/rustc_data_structures/src/owning_ref/mod.rs @@ -3,9 +3,9 @@ /*! # An owning reference. -This crate provides the _owning reference_ types `OwningRef` and `OwningRefMut` +This module provides the _owning reference_ types [`OwningRef`] and [`OwningRefMut`] that enables it to bundle a reference together with the owner of the data it points to. -This allows moving and dropping of an `OwningRef` without needing to recreate the reference. +This allows moving and dropping of an [`OwningRef`] without needing to recreate the reference. This can sometimes be useful because Rust borrowing rules normally prevent moving a type that has been moved from. For example, this kind of code gets rejected: @@ -39,16 +39,16 @@ fn return_owned_and_referenced() -> OwningRef, [u8]> { It works by requiring owner types to dereference to stable memory locations and preventing mutable access to root containers, which in practice requires heap allocation -as provided by `Box`, `Rc`, etc. +as provided by [`Box`], [`Rc`], etc. -Also provided are typedefs for common owner type combinations, +Also provided are type aliases for common owner type combinations, which allow for less verbose type signatures. -For example, `BoxRef` instead of `OwningRef, T>`. +For example, [`BoxRef`] instead of [`OwningRef, T>`]. -The crate also provides the more advanced `OwningHandle` type, +The module also provides the more advanced [`OwningHandle`] type, which allows more freedom in bundling a dependent handle object along with the data it depends on, at the cost of some unsafe needed in the API. -See the documentation around `OwningHandle` for more details. +See the documentation around [`OwningHandle`] for more details. # Examples @@ -250,6 +250,9 @@ use std::mem; /// /// For more details and examples, see the module and method docs. pub struct OwningRef { + // Invariants: + // - `O` implements `StableAddress` or satisfies its safety requirements + // - `reference` is valid as long as `owner` is alive owner: O, reference: *const T, } @@ -264,6 +267,9 @@ pub struct OwningRef { /// /// For more details and examples, see the module and method docs. pub struct OwningRefMut { + // Invariants: + // - `O` implements `StableAddress` or satisfies its safety requirements + // - `reference` is valid as long as `owner` is alive owner: O, reference: *mut T, } @@ -324,12 +330,12 @@ impl OwningRef { /// assert_eq!(*owning_ref, 42); /// } /// ``` - pub fn new(o: O) -> Self + pub fn new(owner: O) -> Self where O: StableAddress, O: Deref, { - OwningRef { reference: &*o, owner: o } + OwningRef { reference: &*owner, owner } } /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait. @@ -337,11 +343,11 @@ impl OwningRef { /// /// This is useful for cases where coherence rules prevents implementing the trait /// without adding a dependency to this crate in a third-party library. - pub unsafe fn new_assert_stable_address(o: O) -> Self + pub unsafe fn new_assert_stable_address(owner: O) -> Self where O: Deref, { - OwningRef { reference: &*o, owner: o } + OwningRef { reference: &*owner, owner } } /// Converts `self` into a new owning reference that points at something reachable @@ -365,7 +371,6 @@ impl OwningRef { /// ``` pub fn map(self, f: F) -> OwningRef where - O: StableAddress, F: FnOnce(&T) -> &U, { OwningRef { reference: f(&self), owner: self.owner } @@ -394,7 +399,6 @@ impl OwningRef { /// ``` pub fn try_map(self, f: F) -> Result, E> where - O: StableAddress, F: FnOnce(&T) -> Result<&U, E>, { Ok(OwningRef { reference: f(&self)?, owner: self.owner }) @@ -407,7 +411,6 @@ impl OwningRef { /// because the user needs to manually uphold this guarantee. pub unsafe fn map_owner(self, f: F) -> OwningRef where - O: StableAddress, P: StableAddress, F: FnOnce(O) -> P, { @@ -482,15 +485,11 @@ impl OwningRef { OwningRef { reference: self.reference, owner: self.owner.into_erased_send_sync() } } - // UNIMPLEMENTED: wrap_owner - - // FIXME: Naming convention? /// A getter for the underlying owner. pub fn owner(&self) -> &O { &self.owner } - // FIXME: Naming convention? /// Discards the reference and retrieves the owner. pub fn into_inner(self) -> O { self.owner @@ -510,12 +509,12 @@ impl OwningRefMut { /// assert_eq!(*owning_ref_mut, 42); /// } /// ``` - pub fn new(mut o: O) -> Self + pub fn new(mut owner: O) -> Self where O: StableAddress, O: DerefMut, { - OwningRefMut { reference: &mut *o, owner: o } + OwningRefMut { reference: &mut *owner, owner } } /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait. @@ -523,11 +522,11 @@ impl OwningRefMut { /// /// This is useful for cases where coherence rules prevents implementing the trait /// without adding a dependency to this crate in a third-party library. - pub unsafe fn new_assert_stable_address(mut o: O) -> Self + pub unsafe fn new_assert_stable_address(mut owner: O) -> Self where O: DerefMut, { - OwningRefMut { reference: &mut *o, owner: o } + OwningRefMut { reference: &mut *owner, owner } } /// Converts `self` into a new _shared_ owning reference that points at @@ -551,7 +550,6 @@ impl OwningRefMut { /// ``` pub fn map(mut self, f: F) -> OwningRef where - O: StableAddress, F: FnOnce(&mut T) -> &U, { OwningRef { reference: f(&mut self), owner: self.owner } @@ -578,7 +576,6 @@ impl OwningRefMut { /// ``` pub fn map_mut(mut self, f: F) -> OwningRefMut where - O: StableAddress, F: FnOnce(&mut T) -> &mut U, { OwningRefMut { reference: f(&mut self), owner: self.owner } @@ -607,7 +604,6 @@ impl OwningRefMut { /// ``` pub fn try_map(mut self, f: F) -> Result, E> where - O: StableAddress, F: FnOnce(&mut T) -> Result<&U, E>, { Ok(OwningRef { reference: f(&mut self)?, owner: self.owner }) @@ -636,7 +632,6 @@ impl OwningRefMut { /// ``` pub fn try_map_mut(mut self, f: F) -> Result, E> where - O: StableAddress, F: FnOnce(&mut T) -> Result<&mut U, E>, { Ok(OwningRefMut { reference: f(&mut self)?, owner: self.owner }) @@ -649,7 +644,6 @@ impl OwningRefMut { /// because the user needs to manually uphold this guarantee. pub unsafe fn map_owner(self, f: F) -> OwningRefMut where - O: StableAddress, P: StableAddress, F: FnOnce(O) -> P, { @@ -703,15 +697,11 @@ impl OwningRefMut { OwningRefMut { reference: self.reference, owner: self.owner.into_erased() } } - // UNIMPLEMENTED: wrap_owner - - // FIXME: Naming convention? /// A getter for the underlying owner. pub fn owner(&self) -> &O { &self.owner } - // FIXME: Naming convention? /// Discards the reference and retrieves the owner. pub fn into_inner(self) -> O { self.owner @@ -724,12 +714,12 @@ impl OwningRefMut { use std::ops::{Deref, DerefMut}; -/// `OwningHandle` is a complement to `OwningRef`. Where `OwningRef` allows +/// `OwningHandle` is a complement to [`OwningRef`]. Where [`OwningRef`] allows /// consumers to pass around an owned object and a dependent reference, /// `OwningHandle` contains an owned object and a dependent _object_. /// -/// `OwningHandle` can encapsulate a `RefMut` along with its associated -/// `RefCell`, or an `RwLockReadGuard` along with its associated `RwLock`. +/// `OwningHandle` can encapsulate a [`cell::RefMut`](RefMut) along with its associated +/// [`RefCell`], or an [`RwLockReadGuard`] along with its associated [`RwLock`](std::sync::RwLock). /// However, the API is completely generic and there are no restrictions on /// what types of owning and dependent objects may be used. /// @@ -740,8 +730,8 @@ use std::ops::{Deref, DerefMut}; /// not outlive the referent of the pointer. /// /// Since the callback needs to dereference a raw pointer, it requires `unsafe` -/// code. To avoid forcing this unsafety on most callers, the `ToHandle` trait is -/// implemented for common data structures. Types that implement `ToHandle` can +/// code. To avoid forcing this unsafety on most callers, the [`ToHandle`] trait is +/// implemented for common data structures. Types that implement [`ToHandle`] can /// be wrapped into an `OwningHandle` without passing a callback. pub struct OwningHandle where @@ -808,8 +798,8 @@ where /// Creates a new `OwningHandle` for a type that implements `ToHandle`. For types /// that don't implement `ToHandle`, callers may invoke `new_with_fn`, which accepts /// a callback to perform the conversion. - pub fn new(o: O) -> Self { - OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle(x) }) + pub fn new(owner: O) -> Self { + OwningHandle::new_with_fn(owner, |x| unsafe { O::Target::to_handle(x) }) } } @@ -819,8 +809,8 @@ where H: DerefMut, { /// Creates a new mutable `OwningHandle` for a type that implements `ToHandleMut`. - pub fn new_mut(o: O) -> Self { - OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle_mut(x) }) + pub fn new_mut(owner: O) -> Self { + OwningHandle::new_with_fn(owner, |x| unsafe { O::Target::to_handle_mut(x) }) } } @@ -833,32 +823,32 @@ where /// a pointer to the object owned by `o`, and the returned value is stored /// as the object to which this `OwningHandle` will forward `Deref` and /// `DerefMut`. - pub fn new_with_fn(o: O, f: F) -> Self + pub fn new_with_fn(owner: O, f: F) -> Self where F: FnOnce(*const O::Target) -> H, { let h: H; { - h = f(o.deref() as *const O::Target); + h = f(owner.deref() as *const O::Target); } - OwningHandle { handle: h, _owner: o } + OwningHandle { handle: h, _owner: owner } } /// Creates a new OwningHandle. The provided callback will be invoked with /// a pointer to the object owned by `o`, and the returned value is stored /// as the object to which this `OwningHandle` will forward `Deref` and /// `DerefMut`. - pub fn try_new(o: O, f: F) -> Result + pub fn try_new(owner: O, f: F) -> Result where F: FnOnce(*const O::Target) -> Result, { let h: H; { - h = f(o.deref() as *const O::Target)?; + h = f(owner.deref() as *const O::Target)?; } - Ok(OwningHandle { handle: h, _owner: o }) + Ok(OwningHandle { handle: h, _owner: owner }) } } @@ -949,15 +939,16 @@ where } } -// ^ FIXME: Is an Into impl for calling into_inner() possible as well? - impl Debug for OwningRef where O: Debug, T: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "OwningRef {{ owner: {:?}, reference: {:?} }}", self.owner(), &**self) + f.debug_struct("OwningRef") + .field("owner", self.owner()) + .field("reference", &&**self) + .finish() } } @@ -967,7 +958,10 @@ where T: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "OwningRefMut {{ owner: {:?}, reference: {:?} }}", self.owner(), &**self) + f.debug_struct("OwningRefMut") + .field("owner", self.owner()) + .field("reference", &&**self) + .finish() } } @@ -985,51 +979,51 @@ unsafe impl CloneStableAddress for OwningRef where O: CloneS unsafe impl Send for OwningRef where O: Send, - for<'a> &'a T: Send, + T: Sync, { } unsafe impl Sync for OwningRef where O: Sync, - for<'a> &'a T: Sync, + T: Sync, { } unsafe impl Send for OwningRefMut where O: Send, - for<'a> &'a mut T: Send, + T: Send, { } unsafe impl Sync for OwningRefMut where O: Sync, - for<'a> &'a mut T: Sync, + T: Sync, { } impl Debug for dyn Erased { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "",) + f.write_str("") } } -impl PartialEq for OwningRef +impl PartialEq> for OwningRef where - T: PartialEq, + T: PartialEq, { - fn eq(&self, other: &Self) -> bool { + fn eq(&self, other: &OwningRef) -> bool { self.deref().eq(other.deref()) } } impl Eq for OwningRef where T: Eq {} -impl PartialOrd for OwningRef +impl PartialOrd> for OwningRef where - T: PartialOrd, + T: PartialOrd, { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &OwningRef) -> Option { self.deref().partial_cmp(other.deref()) } } @@ -1052,22 +1046,22 @@ where } } -impl PartialEq for OwningRefMut +impl PartialEq> for OwningRefMut where - T: PartialEq, + T: PartialEq, { - fn eq(&self, other: &Self) -> bool { + fn eq(&self, other: &OwningRefMut) -> bool { self.deref().eq(other.deref()) } } impl Eq for OwningRefMut where T: Eq {} -impl PartialOrd for OwningRefMut +impl PartialOrd> for OwningRefMut where - T: PartialOrd, + T: PartialOrd, { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &OwningRefMut) -> Option { self.deref().partial_cmp(other.deref()) } } @@ -1091,7 +1085,7 @@ where } ///////////////////////////////////////////////////////////////////////////// -// std types integration and convenience type defs +// std types integration and convenience type aliases ///////////////////////////////////////////////////////////////////////////// use std::cell::{Ref, RefCell, RefMut}; @@ -1117,41 +1111,41 @@ impl ToHandleMut for RefCell { // about which handle creation to use (i.e., read() vs try_read()) as well as // what to do with error results. -/// Typedef of an owning reference that uses a `Box` as the owner. +/// Type alias of an owning reference that uses a [`Box`] as the owner. pub type BoxRef = OwningRef, U>; -/// Typedef of an owning reference that uses a `Vec` as the owner. -pub type VecRef = OwningRef, U>; -/// Typedef of an owning reference that uses a `String` as the owner. -pub type StringRef = OwningRef; +/// Typedef of an owning reference that uses a [`Vec`] as the owner. +pub type VecRef = OwningRef, U>; +/// Typedef of an owning reference that uses a [`String`] as the owner. +pub type StringRef = OwningRef; -/// Typedef of an owning reference that uses an `Rc` as the owner. +/// Type alias of an owning reference that uses an [`Rc`] as the owner. pub type RcRef = OwningRef, U>; -/// Typedef of an owning reference that uses an `Arc` as the owner. +/// Type alias of an owning reference that uses an [`Arc`] as the owner. pub type ArcRef = OwningRef, U>; -/// Typedef of an owning reference that uses a `Ref` as the owner. +/// Type alias of an owning reference that uses a [`cell::Ref`](Ref) as the owner. pub type RefRef<'a, T, U = T> = OwningRef, U>; -/// Typedef of an owning reference that uses a `RefMut` as the owner. +/// Type alias of an owning reference that uses a [`cell::RefMut`](RefMut) as the owner. pub type RefMutRef<'a, T, U = T> = OwningRef, U>; -/// Typedef of an owning reference that uses a `MutexGuard` as the owner. +/// Type alias of an owning reference that uses a [`MutexGuard`] as the owner. pub type MutexGuardRef<'a, T, U = T> = OwningRef, U>; -/// Typedef of an owning reference that uses an `RwLockReadGuard` as the owner. +/// Type alias of an owning reference that uses an [`RwLockReadGuard`] as the owner. pub type RwLockReadGuardRef<'a, T, U = T> = OwningRef, U>; -/// Typedef of an owning reference that uses an `RwLockWriteGuard` as the owner. +/// Type alias of an owning reference that uses an [`RwLockWriteGuard`] as the owner. pub type RwLockWriteGuardRef<'a, T, U = T> = OwningRef, U>; -/// Typedef of a mutable owning reference that uses a `Box` as the owner. +/// Type alias of a mutable owning reference that uses a [`Box`] as the owner. pub type BoxRefMut = OwningRefMut, U>; -/// Typedef of a mutable owning reference that uses a `Vec` as the owner. +/// Type alias of a mutable owning reference that uses a [`Vec`] as the owner. pub type VecRefMut = OwningRefMut, U>; -/// Typedef of a mutable owning reference that uses a `String` as the owner. +/// Typedef of a mutable owning reference that uses a [`String`] as the owner. pub type StringRefMut = OwningRefMut; -/// Typedef of a mutable owning reference that uses a `RefMut` as the owner. +/// Type alias of a mutable owning reference that uses a [`RefMut`] as the owner. pub type RefMutRefMut<'a, T, U = T> = OwningRefMut, U>; -/// Typedef of a mutable owning reference that uses a `MutexGuard` as the owner. +/// Type alias of a mutable owning reference that uses a [`MutexGuard`] as the owner. pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut, U>; -/// Typedef of a mutable owning reference that uses an `RwLockWriteGuard` as the owner. +/// Type alias of a mutable owning reference that uses an [`RwLockWriteGuard`] as the owner. pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRef, U>; unsafe impl<'a, T: 'a> IntoErased<'a> for Box { @@ -1197,15 +1191,15 @@ unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc { } } -/// Typedef of an owning reference that uses an erased `Box` as the owner. -pub type ErasedBoxRef = OwningRef, U>; -/// Typedef of an owning reference that uses an erased `Rc` as the owner. -pub type ErasedRcRef = OwningRef, U>; -/// Typedef of an owning reference that uses an erased `Arc` as the owner. -pub type ErasedArcRef = OwningRef, U>; +/// Typedef of an owning reference that uses an erased [`Box`] as the owner. +pub type ErasedBoxRef = BoxRef; +/// Typedef of an owning reference that uses an erased [`Rc`] as the owner. +pub type ErasedRcRef = RcRef; +/// Typedef of an owning reference that uses an erased [`Arc`] as the owner. +pub type ErasedArcRef = ArcRef; -/// Typedef of a mutable owning reference that uses an erased `Box` as the owner. -pub type ErasedBoxRefMut = OwningRefMut, U>; +/// Typedef of a mutable owning reference that uses an erased [`Box`] as the owner. +pub type ErasedBoxRefMut = BoxRefMut; #[cfg(test)] mod tests;