From e055b88b132793a9f51306aab198fa874abab31f Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Mon, 18 Jan 2021 18:32:09 +0100 Subject: [PATCH 1/4] Make OwningRef and OwningRefMut more sound by adding lifetime parameters (breaking change!) --- src/lib.rs | 163 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 70 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fa2f15a..b54067b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ bundled together in a wrapper type that ensure that lifetime constraint: # extern crate owning_ref; # use owning_ref::OwningRef; # fn main() { -fn return_owned_and_referenced() -> OwningRef, [u8]> { +fn return_owned_and_referenced() -> OwningRef<'static, Vec, [u8]> { let v = vec![1, 2, 3, 4]; let or = OwningRef::new(v); let or = or.map(|v| &v[1..3]); @@ -161,7 +161,7 @@ use std::sync::Arc; fn main() { use std::thread; - fn par_sum(rc: ArcRef<[i32]>) -> i32 { + fn par_sum(rc: ArcRef<'static, [i32]>) -> i32 { if rc.len() == 0 { return 0; } else if rc.len() == 1 { @@ -245,6 +245,7 @@ fn main() { extern crate stable_deref_trait; pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress}; +use std::marker::PhantomData; /// An owning reference. /// @@ -255,9 +256,10 @@ pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as C /// The owner is usually a pointer that points at some base type. /// /// For more details and examples, see the module and method docs. -pub struct OwningRef { +pub struct OwningRef<'t, O, T: ?Sized> { owner: O, reference: *const T, + marker: PhantomData<&'t T>, } /// An mutable owning reference. @@ -269,9 +271,10 @@ pub struct OwningRef { /// The owner is usually a pointer that points at some base type. /// /// For more details and examples, see the module and method docs. -pub struct OwningRefMut { +pub struct OwningRefMut<'t, O, T: ?Sized> { owner: O, reference: *mut T, + marker: PhantomData<&'t T>, } /// Helper trait for an erased concrete type an owner dereferences to. @@ -294,7 +297,7 @@ pub unsafe trait IntoErased<'a> { // OwningRef ///////////////////////////////////////////////////////////////////////////// -impl OwningRef { +impl<'t, O, T: ?Sized> OwningRef<'t, O, T> { /// Creates a new owning reference from a owner /// initialized to the direct dereference of it. /// @@ -315,6 +318,7 @@ impl OwningRef { OwningRef { reference: &*o, owner: o, + marker: PhantomData, } } @@ -329,6 +333,7 @@ impl OwningRef { OwningRef { reference: &*o, owner: o, + marker: PhantomData, } } @@ -352,13 +357,14 @@ impl OwningRef { /// assert_eq!(*owning_ref, 3); /// } /// ``` - pub fn map(self, f: F) -> OwningRef + pub fn map(self, f: F) -> OwningRef<'t, O, U> where O: StableAddress, F: FnOnce(&T) -> &U { OwningRef { reference: f(&self), owner: self.owner, + marker: PhantomData, } } @@ -384,13 +390,14 @@ impl OwningRef { /// assert_eq!(*owning_ref, 2); /// } /// ``` - pub fn map_with_owner(self, f: F) -> OwningRef + pub fn map_with_owner(self, f: F) -> OwningRef<'t, O, U> where O: StableAddress, F: for<'a> FnOnce(&'a O, &'a T) -> &'a U { OwningRef { reference: f(&self.owner, &self), owner: self.owner, + marker: PhantomData, } } @@ -416,13 +423,14 @@ impl OwningRef { /// assert_eq!(*owning_ref.unwrap(), 3); /// } /// ``` - pub fn try_map(self, f: F) -> Result, E> + 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, + marker: PhantomData, }) } @@ -449,13 +457,14 @@ impl OwningRef { /// assert_eq!(*owning_ref.unwrap(), 2); /// } /// ``` - pub fn try_map_with_owner(self, f: F) -> Result, E> + pub fn try_map_with_owner(self, f: F) -> Result, E> where O: StableAddress, F: for<'a> FnOnce(&'a O, &'a T) -> Result<&'a U, E> { Ok(OwningRef { reference: f(&self.owner, &self)?, owner: self.owner, + marker: PhantomData, }) } @@ -464,7 +473,7 @@ impl OwningRef { /// The new owner type needs to still contain the original owner in some way /// so that the reference into it remains valid. This function is marked unsafe /// because the user needs to manually uphold this guarantee. - pub unsafe fn map_owner(self, f: F) -> OwningRef + pub unsafe fn map_owner(self, f: F) -> OwningRef<'t, P, T> where O: StableAddress, P: StableAddress, F: FnOnce(O) -> P @@ -472,6 +481,7 @@ impl OwningRef { OwningRef { reference: self.reference, owner: f(self.owner), + marker: PhantomData, } } @@ -480,10 +490,11 @@ impl OwningRef { /// /// This can be used to safely erase the owner of any `OwningRef` /// to a `OwningRef, T>`. - pub fn map_owner_box(self) -> OwningRef, T> { + pub fn map_owner_box(self) -> OwningRef<'t, Box, T> { OwningRef { reference: self.reference, owner: Box::new(self.owner), + marker: PhantomData, } } @@ -519,12 +530,13 @@ impl OwningRef { /// assert_eq!(*owning_refs[1], 1); /// } /// ``` - pub fn erase_owner<'a>(self) -> OwningRef + pub fn erase_owner<'a>(self) -> OwningRef<'t, O::Erased, T> where O: IntoErased<'a>, { OwningRef { reference: self.reference, owner: self.owner.into_erased(), + marker: PhantomData, } } @@ -541,7 +553,7 @@ impl OwningRef { } } -impl OwningRefMut { +impl<'t, O, T: ?Sized> OwningRefMut<'t, O, T> { /// Creates a new owning reference from a owner /// initialized to the direct dereference of it. /// @@ -562,6 +574,7 @@ impl OwningRefMut { OwningRefMut { reference: &mut *o, owner: o, + marker: PhantomData, } } @@ -576,6 +589,7 @@ impl OwningRefMut { OwningRefMut { reference: &mut *o, owner: o, + marker: PhantomData, } } @@ -599,13 +613,14 @@ impl OwningRefMut { /// assert_eq!(*owning_ref, 3); /// } /// ``` - pub fn map(mut self, f: F) -> OwningRef + pub fn map(mut self, f: F) -> OwningRef<'t, O, U> where O: StableAddress, F: FnOnce(&mut T) -> &U { OwningRef { reference: f(&mut self), owner: self.owner, + marker: PhantomData, } } @@ -629,13 +644,14 @@ impl OwningRefMut { /// assert_eq!(*owning_ref_mut, 3); /// } /// ``` - pub fn map_mut(mut self, f: F) -> OwningRefMut + pub fn map_mut(mut self, f: F) -> OwningRefMut<'t, O, U> where O: StableAddress, F: FnOnce(&mut T) -> &mut U { OwningRefMut { reference: f(&mut self), owner: self.owner, + marker: PhantomData, } } @@ -661,13 +677,14 @@ impl OwningRefMut { /// assert_eq!(*owning_ref.unwrap(), 3); /// } /// ``` - pub fn try_map(mut self, f: F) -> Result, E> + 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, + marker: PhantomData, }) } @@ -693,13 +710,14 @@ impl OwningRefMut { /// assert_eq!(*owning_ref_mut.unwrap(), 3); /// } /// ``` - pub fn try_map_mut(mut self, f: F) -> Result, E> + 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, + marker: PhantomData, }) } @@ -708,7 +726,7 @@ impl OwningRefMut { /// The new owner type needs to still contain the original owner in some way /// so that the reference into it remains valid. This function is marked unsafe /// because the user needs to manually uphold this guarantee. - pub unsafe fn map_owner(self, f: F) -> OwningRefMut + pub unsafe fn map_owner(self, f: F) -> OwningRefMut<'t, P, T> where O: StableAddress, P: StableAddress, F: FnOnce(O) -> P @@ -716,6 +734,7 @@ impl OwningRefMut { OwningRefMut { reference: self.reference, owner: f(self.owner), + marker: PhantomData, } } @@ -724,10 +743,11 @@ impl OwningRefMut { /// /// This can be used to safely erase the owner of any `OwningRefMut` /// to a `OwningRefMut, T>`. - pub fn map_owner_box(self) -> OwningRefMut, T> { + pub fn map_owner_box(self) -> OwningRefMut<'t, Box, T> { OwningRefMut { reference: self.reference, owner: Box::new(self.owner), + marker: PhantomData, } } @@ -763,12 +783,13 @@ impl OwningRefMut { /// assert_eq!(*owning_refs_mut[1], 1); /// } /// ``` - pub fn erase_owner<'a>(self) -> OwningRefMut + pub fn erase_owner<'a>(self) -> OwningRefMut<'t, O::Erased, T> where O: IntoErased<'a>, { OwningRefMut { reference: self.reference, owner: self.owner.into_erased(), + marker: PhantomData, } } @@ -944,7 +965,7 @@ use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering}; use std::hash::{Hash, Hasher}; use std::borrow::Borrow; -impl Deref for OwningRef { +impl<'t, O, T: ?Sized> Deref for OwningRef<'t, O, T> { type Target = T; fn deref(&self) -> &T { @@ -954,7 +975,7 @@ impl Deref for OwningRef { } } -impl Deref for OwningRefMut { +impl<'t, O, T: ?Sized> Deref for OwningRefMut<'t, O, T> { type Target = T; fn deref(&self) -> &T { @@ -964,7 +985,7 @@ impl Deref for OwningRefMut { } } -impl DerefMut for OwningRefMut { +impl<'t, O, T: ?Sized> DerefMut for OwningRefMut<'t, O, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.reference @@ -972,35 +993,35 @@ impl DerefMut for OwningRefMut { } } -unsafe impl StableAddress for OwningRef {} +unsafe impl<'t, O, T: ?Sized> StableAddress for OwningRef<'t, O, T> {} -unsafe impl StableAddress for OwningRefMut {} +unsafe impl<'t, O, T: ?Sized> StableAddress for OwningRefMut<'t, O, T> {} -impl AsRef for OwningRef { +impl<'t, O, T: ?Sized> AsRef for OwningRef<'t, O, T> { fn as_ref(&self) -> &T { &*self } } -impl AsRef for OwningRefMut { +impl<'t, O, T: ?Sized> AsRef for OwningRefMut<'t, O, T> { fn as_ref(&self) -> &T { &*self } } -impl AsMut for OwningRefMut { +impl<'t, O, T: ?Sized> AsMut for OwningRefMut<'t, O, T> { fn as_mut(&mut self) -> &mut T { &mut *self } } -impl Borrow for OwningRef { +impl<'t, O, T: ?Sized> Borrow for OwningRef<'t, O, T> { fn borrow(&self) -> &T { &*self } } -impl From for OwningRef +impl<'t, O, T: ?Sized> From for OwningRef<'t, O, T> where O: StableAddress, O: Deref, { @@ -1009,7 +1030,7 @@ impl From for OwningRef } } -impl From for OwningRefMut +impl<'t, O, T: ?Sized> From for OwningRefMut<'t, O, T> where O: StableAddress, O: DerefMut { @@ -1018,7 +1039,7 @@ impl From for OwningRefMut } } -impl From> for OwningRef +impl<'t1: 't2, 't2, O, T: ?Sized> From> for OwningRef<'t2, O, T> where O: StableAddress, O: DerefMut { @@ -1026,13 +1047,14 @@ impl From> for OwningRef OwningRef { owner: other.owner, reference: other.reference, + marker: PhantomData, } } } // ^ FIXME: Is a Into impl for calling into_owner() possible as well? -impl Debug for OwningRef +impl<'t, O, T: ?Sized> Debug for OwningRef<'t, O, T> where O: Debug, T: Debug, { @@ -1044,7 +1066,7 @@ impl Debug for OwningRef } } -impl Debug for OwningRefMut +impl<'t, O, T: ?Sized> Debug for OwningRefMut<'t, O, T> where O: Debug, T: Debug, { @@ -1056,28 +1078,29 @@ impl Debug for OwningRefMut } } -impl Clone for OwningRef +impl<'t, O, T: ?Sized> Clone for OwningRef<'t, O, T> where O: CloneStableAddress, { fn clone(&self) -> Self { OwningRef { owner: self.owner.clone(), reference: self.reference, + marker: PhantomData, } } } -unsafe impl CloneStableAddress for OwningRef +unsafe impl<'t, O, T: ?Sized> CloneStableAddress for OwningRef<'t, O, T> where O: CloneStableAddress {} -unsafe impl Send for OwningRef +unsafe impl<'t, O, T: ?Sized> Send for OwningRef<'t, O, T> where O: Send, for<'a> (&'a T): Send {} -unsafe impl Sync for OwningRef +unsafe impl<'t, O, T: ?Sized> Sync for OwningRef<'t, O, T> where O: Sync, for<'a> (&'a T): Sync {} -unsafe impl Send for OwningRefMut +unsafe impl<'t, O, T: ?Sized> Send for OwningRefMut<'t, O, T> where O: Send, for<'a> (&'a mut T): Send {} -unsafe impl Sync for OwningRefMut +unsafe impl<'t, O, T: ?Sized> Sync for OwningRefMut<'t, O, T> where O: Sync, for<'a> (&'a mut T): Sync {} impl Debug for dyn Erased { @@ -1086,53 +1109,53 @@ impl Debug for dyn Erased { } } -impl PartialEq for OwningRef where T: PartialEq { +impl<'t, O, T: ?Sized> PartialEq for OwningRef<'t, O, T> where T: PartialEq { fn eq(&self, other: &Self) -> bool { (&*self as &T).eq(&*other as &T) } } -impl Eq for OwningRef where T: Eq {} +impl<'t, O, T: ?Sized> Eq for OwningRef<'t, O, T> where T: Eq {} -impl PartialOrd for OwningRef where T: PartialOrd { +impl<'t, O, T: ?Sized> PartialOrd for OwningRef<'t, O, T> where T: PartialOrd { fn partial_cmp(&self, other: &Self) -> Option { (&*self as &T).partial_cmp(&*other as &T) } } -impl Ord for OwningRef where T: Ord { +impl<'t, O, T: ?Sized> Ord for OwningRef<'t, O, T> where T: Ord { fn cmp(&self, other: &Self) -> Ordering { (&*self as &T).cmp(&*other as &T) } } -impl Hash for OwningRef where T: Hash { +impl<'t, O, T: ?Sized> Hash for OwningRef<'t, O, T> where T: Hash { fn hash(&self, state: &mut H) { (&*self as &T).hash(state); } } -impl PartialEq for OwningRefMut where T: PartialEq { +impl<'t, O, T: ?Sized> PartialEq for OwningRefMut<'t, O, T> where T: PartialEq { fn eq(&self, other: &Self) -> bool { (&*self as &T).eq(&*other as &T) } } -impl Eq for OwningRefMut where T: Eq {} +impl<'t, O, T: ?Sized> Eq for OwningRefMut<'t, O, T> where T: Eq {} -impl PartialOrd for OwningRefMut where T: PartialOrd { +impl<'t, O, T: ?Sized> PartialOrd for OwningRefMut<'t, O, T> where T: PartialOrd { fn partial_cmp(&self, other: &Self) -> Option { (&*self as &T).partial_cmp(&*other as &T) } } -impl Ord for OwningRefMut where T: Ord { +impl<'t, O, T: ?Sized> Ord for OwningRefMut<'t, O, T> where T: Ord { fn cmp(&self, other: &Self) -> Ordering { (&*self as &T).cmp(&*other as &T) } } -impl Hash for OwningRefMut where T: Hash { +impl<'t, O, T: ?Sized> Hash for OwningRefMut<'t, O, T> where T: Hash { fn hash(&self, state: &mut H) { (&*self as &T).hash(state); } @@ -1163,41 +1186,41 @@ impl ToHandleMut for RefCell { // what to do with error results. /// Typedef of a owning reference that uses a `Box` as the owner. -pub type BoxRef = OwningRef, U>; +pub type BoxRef<'u, T, U = T> = OwningRef<'u, Box, U>; /// Typedef of a owning reference that uses a `Vec` as the owner. -pub type VecRef = OwningRef, U>; +pub type VecRef<'u, T, U = T> = OwningRef<'u, Vec, U>; /// Typedef of a owning reference that uses a `String` as the owner. -pub type StringRef = OwningRef; +pub type StringRef<'u> = OwningRef<'u, String, str>; /// Typedef of a owning reference that uses a `Rc` as the owner. -pub type RcRef = OwningRef, U>; +pub type RcRef<'u, T, U = T> = OwningRef<'u, Rc, U>; /// Typedef of a owning reference that uses a `Arc` as the owner. -pub type ArcRef = OwningRef, U>; +pub type ArcRef<'u, T, U = T> = OwningRef<'u, Arc, U>; /// Typedef of a owning reference that uses a `Ref` as the owner. -pub type RefRef<'a, T, U = T> = OwningRef, U>; +pub type RefRef<'a, T, U = T> = OwningRef<'a, Ref<'a, T>, U>; /// Typedef of a owning reference that uses a `RefMut` as the owner. -pub type RefMutRef<'a, T, U = T> = OwningRef, U>; +pub type RefMutRef<'a, T, U = T> = OwningRef<'a, RefMut<'a, T>, U>; /// Typedef of a owning reference that uses a `MutexGuard` as the owner. -pub type MutexGuardRef<'a, T, U = T> = OwningRef, U>; +pub type MutexGuardRef<'a, T, U = T> = OwningRef<'a, MutexGuard<'a, T>, U>; /// Typedef of a owning reference that uses a `RwLockReadGuard` as the owner. -pub type RwLockReadGuardRef<'a, T, U = T> = OwningRef, U>; +pub type RwLockReadGuardRef<'a, T, U = T> = OwningRef<'a, RwLockReadGuard<'a, T>, U>; /// Typedef of a owning reference that uses a `RwLockWriteGuard` as the owner. -pub type RwLockWriteGuardRef<'a, T, U = T> = OwningRef, U>; +pub type RwLockWriteGuardRef<'a, T, U = T> = OwningRef<'a, RwLockWriteGuard<'a, T>, U>; /// Typedef of a mutable owning reference that uses a `Box` as the owner. -pub type BoxRefMut = OwningRefMut, U>; +pub type BoxRefMut<'u, T, U = T> = OwningRefMut<'u, Box, U>; /// Typedef of a mutable owning reference that uses a `Vec` as the owner. -pub type VecRefMut = OwningRefMut, U>; +pub type VecRefMut<'u, T, U = T> = OwningRefMut<'u, Vec, U>; /// Typedef of a mutable owning reference that uses a `String` as the owner. -pub type StringRefMut = OwningRefMut; +pub type StringRefMut<'u, > = OwningRefMut<'u, String, str>; /// Typedef of a mutable owning reference that uses a `RefMut` as the owner. -pub type RefMutRefMut<'a, T, U = T> = OwningRefMut, U>; +pub type RefMutRefMut<'a, T, U = T> = OwningRefMut<'a, RefMut<'a, T>, U>; /// Typedef of a mutable owning reference that uses a `MutexGuard` as the owner. -pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut, U>; +pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut<'a, MutexGuard<'a, T>, U>; /// Typedef of a mutable owning reference that uses a `RwLockWriteGuard` as the owner. -pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRefMut, U>; +pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRefMut<'a, RwLockWriteGuard<'a, T>, U>; unsafe impl<'a, T: 'a> IntoErased<'a> for Box { type Erased = Box; @@ -1219,14 +1242,14 @@ unsafe impl<'a, T: 'a> IntoErased<'a> for Arc { } /// Typedef of a owning reference that uses an erased `Box` as the owner. -pub type ErasedBoxRef = OwningRef, U>; +pub type ErasedBoxRef<'u, U> = OwningRef<'u, Box, U>; /// Typedef of a owning reference that uses an erased `Rc` as the owner. -pub type ErasedRcRef = OwningRef, U>; +pub type ErasedRcRef<'u, U> = OwningRef<'u, Rc, U>; /// Typedef of a owning reference that uses an erased `Arc` as the owner. -pub type ErasedArcRef = OwningRef, U>; +pub type ErasedArcRef<'u, U> = OwningRef<'u, Arc, U>; /// Typedef of a mutable owning reference that uses an erased `Box` as the owner. -pub type ErasedBoxRefMut = OwningRefMut, U>; +pub type ErasedBoxRefMut<'u, U> = OwningRefMut<'u, Box, U>; #[cfg(test)] mod tests { From 5e41145c453002db07dd7a894da0a67d5f4275db Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Mon, 18 Jan 2021 18:35:49 +0100 Subject: [PATCH 2/4] Add explicit elided lifetimes in documentaiton and tests --- src/lib.rs | 92 +++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b54067b..f85b701 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,7 @@ and preventing mutable access to root containers, which in practice requires hea as provided by `Box`, `Rc`, etc. Also provided are typedefs for common owner type combinations, -which allow for less verbose type signatures. For example, `BoxRef` instead of `OwningRef, T>`. +which allow for less verbose type signatures. For example, `BoxRef<'t, T>` instead of `OwningRef<'t, Box, T>`. The crate also provides the more advanced `OwningHandle` type, which allows more freedom in bundling a dependent handle object @@ -488,8 +488,8 @@ impl<'t, O, T: ?Sized> OwningRef<'t, O, T> { /// Converts `self` into a new owning reference where the owner is wrapped /// in an additional `Box`. /// - /// This can be used to safely erase the owner of any `OwningRef` - /// to a `OwningRef, T>`. + /// This can be used to safely erase the owner of any `OwningRef<'t, O, T>` + /// to a `OwningRef<'t, Box, T>`. pub fn map_owner_box(self) -> OwningRef<'t, Box, T> { OwningRef { reference: self.reference, @@ -511,19 +511,19 @@ impl<'t, O, T: ?Sized> OwningRef<'t, O, T> { /// // NB: Using the concrete types here for explicitnes. /// // For less verbose code type aliases like `BoxRef` are provided. /// - /// let owning_ref_a: OwningRef, [i32; 4]> + /// let owning_ref_a: OwningRef<'_, Box<[i32; 4]>, [i32; 4]> /// = OwningRef::new(Box::new([1, 2, 3, 4])); /// - /// let owning_ref_b: OwningRef>, Vec<(i32, bool)>> + /// let owning_ref_b: OwningRef<'_, Box>, Vec<(i32, bool)>> /// = OwningRef::new(Box::new(vec![(0, false), (1, true)])); /// - /// let owning_ref_a: OwningRef, i32> + /// let owning_ref_a: OwningRef<'_, Box<[i32; 4]>, i32> /// = owning_ref_a.map(|a| &a[0]); /// - /// let owning_ref_b: OwningRef>, i32> + /// let owning_ref_b: OwningRef<'_, Box>, i32> /// = owning_ref_b.map(|a| &a[1].0); /// - /// let owning_refs: [OwningRef, i32>; 2] + /// let owning_refs: [OwningRef<'_, Box, i32>; 2] /// = [owning_ref_a.erase_owner(), owning_ref_b.erase_owner()]; /// /// assert_eq!(*owning_refs[0], 1); @@ -741,8 +741,8 @@ impl<'t, O, T: ?Sized> OwningRefMut<'t, O, T> { /// Converts `self` into a new owning reference where the owner is wrapped /// in an additional `Box`. /// - /// This can be used to safely erase the owner of any `OwningRefMut` - /// to a `OwningRefMut, T>`. + /// This can be used to safely erase the owner of any `OwningRefMut<'_, O, T>` + /// to a `OwningRefMut<'_, Box, T>`. pub fn map_owner_box(self) -> OwningRefMut<'t, Box, T> { OwningRefMut { reference: self.reference, @@ -764,19 +764,19 @@ impl<'t, O, T: ?Sized> OwningRefMut<'t, O, T> { /// // NB: Using the concrete types here for explicitnes. /// // For less verbose code type aliases like `BoxRef` are provided. /// - /// let owning_ref_mut_a: OwningRefMut, [i32; 4]> + /// let owning_ref_mut_a: OwningRefMut<'_, Box<[i32; 4]>, [i32; 4]> /// = OwningRefMut::new(Box::new([1, 2, 3, 4])); /// - /// let owning_ref_mut_b: OwningRefMut>, Vec<(i32, bool)>> + /// let owning_ref_mut_b: OwningRefMut<'_, Box>, Vec<(i32, bool)>> /// = OwningRefMut::new(Box::new(vec![(0, false), (1, true)])); /// - /// let owning_ref_mut_a: OwningRefMut, i32> + /// let owning_ref_mut_a: OwningRefMut<'_, Box<[i32; 4]>, i32> /// = owning_ref_mut_a.map_mut(|a| &mut a[0]); /// - /// let owning_ref_mut_b: OwningRefMut>, i32> + /// let owning_ref_mut_b: OwningRefMut<'_, Box>, i32> /// = owning_ref_mut_b.map_mut(|a| &mut a[1].0); /// - /// let owning_refs_mut: [OwningRefMut, i32>; 2] + /// let owning_refs_mut: [OwningRefMut<'_, Box, i32>; 2] /// = [owning_ref_mut_a.erase_owner(), owning_ref_mut_b.erase_owner()]; /// /// assert_eq!(*owning_refs_mut[0], 1); @@ -1043,7 +1043,7 @@ impl<'t1: 't2, 't2, O, T: ?Sized> From> for OwningRef<'t where O: StableAddress, O: DerefMut { - fn from(other: OwningRefMut) -> Self { + fn from(other: OwningRefMut<'_, O, T>) -> Self { OwningRef { owner: other.owner, reference: other.reference, @@ -1270,13 +1270,13 @@ mod tests { #[test] fn new_deref() { - let or: OwningRef, ()> = OwningRef::new(Box::new(())); + let or: OwningRef<'_, Box<()>, ()> = OwningRef::new(Box::new(())); assert_eq!(&*or, &()); } #[test] fn into() { - let or: OwningRef, ()> = Box::new(()).into(); + let or: OwningRef<'_, Box<()>, ()> = Box::new(()).into(); assert_eq!(&*or, &()); } @@ -1485,16 +1485,16 @@ mod tests { #[test] fn total_erase() { - let a: OwningRef, [u8]> + let a: OwningRef<'_, Vec, [u8]> = OwningRef::new(vec![]).map(|x| &x[..]); - let b: OwningRef, [u8]> + let b: OwningRef<'_, Box<[u8]>, [u8]> = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); - let c: OwningRef>, [u8]> = unsafe {a.map_owner(Rc::new)}; - let d: OwningRef>, [u8]> = unsafe {b.map_owner(Rc::new)}; + let c: OwningRef<'_, Rc>, [u8]> = unsafe {a.map_owner(Rc::new)}; + let d: OwningRef<'_, Rc>, [u8]> = unsafe {b.map_owner(Rc::new)}; - let e: OwningRef, [u8]> = c.erase_owner(); - let f: OwningRef, [u8]> = d.erase_owner(); + let e: OwningRef<'_, Rc, [u8]> = c.erase_owner(); + let f: OwningRef<'_, Rc, [u8]> = d.erase_owner(); let _g = e.clone(); let _h = f.clone(); @@ -1502,16 +1502,16 @@ mod tests { #[test] fn total_erase_box() { - let a: OwningRef, [u8]> + let a: OwningRef<'_, Vec, [u8]> = OwningRef::new(vec![]).map(|x| &x[..]); - let b: OwningRef, [u8]> + let b: OwningRef<'_, Box<[u8]>, [u8]> = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); - let c: OwningRef>, [u8]> = a.map_owner_box(); - let d: OwningRef>, [u8]> = b.map_owner_box(); + let c: OwningRef<'_, Box>, [u8]> = a.map_owner_box(); + let d: OwningRef<'_, Box>, [u8]> = b.map_owner_box(); - let _e: OwningRef, [u8]> = c.erase_owner(); - let _f: OwningRef, [u8]> = d.erase_owner(); + let _e: OwningRef<'_, Box, [u8]> = c.erase_owner(); + let _f: OwningRef<'_, Box, [u8]> = d.erase_owner(); } #[test] @@ -1686,19 +1686,19 @@ mod tests { #[test] fn new_deref() { - let or: OwningRefMut, ()> = OwningRefMut::new(Box::new(())); + let or: OwningRefMut<'_, Box<()>, ()> = OwningRefMut::new(Box::new(())); assert_eq!(&*or, &()); } #[test] fn new_deref_mut() { - let mut or: OwningRefMut, ()> = OwningRefMut::new(Box::new(())); + let mut or: OwningRefMut<'_, Box<()>, ()> = OwningRefMut::new(Box::new(())); assert_eq!(&mut *or, &mut ()); } #[test] fn mutate() { - let mut or: OwningRefMut, usize> = OwningRefMut::new(Box::new(0)); + let mut or: OwningRefMut<'_, Box, usize> = OwningRefMut::new(Box::new(0)); assert_eq!(&*or, &0); *or = 1; assert_eq!(&*or, &1); @@ -1706,7 +1706,7 @@ mod tests { #[test] fn into() { - let or: OwningRefMut, ()> = Box::new(()).into(); + let or: OwningRefMut<'_, Box<()>, ()> = Box::new(()).into(); assert_eq!(&*or, &()); } @@ -1937,30 +1937,30 @@ mod tests { #[test] fn total_erase() { - let a: OwningRefMut, [u8]> + let a: OwningRefMut<'_, Vec, [u8]> = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); - let b: OwningRefMut, [u8]> + let b: OwningRefMut<'_, Box<[u8]>, [u8]> = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); - let c: OwningRefMut>, [u8]> = unsafe {a.map_owner(Box::new)}; - let d: OwningRefMut>, [u8]> = unsafe {b.map_owner(Box::new)}; + let c: OwningRefMut<'_, Box>, [u8]> = unsafe {a.map_owner(Box::new)}; + let d: OwningRefMut<'_, Box>, [u8]> = unsafe {b.map_owner(Box::new)}; - let _e: OwningRefMut, [u8]> = c.erase_owner(); - let _f: OwningRefMut, [u8]> = d.erase_owner(); + let _e: OwningRefMut<'_, Box, [u8]> = c.erase_owner(); + let _f: OwningRefMut<'_, Box, [u8]> = d.erase_owner(); } #[test] fn total_erase_box() { - let a: OwningRefMut, [u8]> + let a: OwningRefMut<'_, Vec, [u8]> = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); - let b: OwningRefMut, [u8]> + let b: OwningRefMut<'_, Box<[u8]>, [u8]> = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); - let c: OwningRefMut>, [u8]> = a.map_owner_box(); - let d: OwningRefMut>, [u8]> = b.map_owner_box(); + let c: OwningRefMut<'_, Box>, [u8]> = a.map_owner_box(); + let d: OwningRefMut<'_, Box>, [u8]> = b.map_owner_box(); - let _e: OwningRefMut, [u8]> = c.erase_owner(); - let _f: OwningRefMut, [u8]> = d.erase_owner(); + let _e: OwningRefMut<'_, Box, [u8]> = c.erase_owner(); + let _f: OwningRefMut<'_, Box, [u8]> = d.erase_owner(); } #[test] From b26010a7727175e9cc91e36f2cc938f3967c1f4f Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Mon, 18 Jan 2021 18:39:40 +0100 Subject: [PATCH 3/4] Also fix #61 --- src/lib.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f85b701..7e25ff9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -793,18 +793,6 @@ impl<'t, O, T: ?Sized> OwningRefMut<'t, O, T> { } } - // TODO: wrap_owner - - /// A reference to the underlying owner. - pub fn as_owner(&self) -> &O { - &self.owner - } - - /// A mutable reference to the underlying owner. - pub fn as_owner_mut(&mut self) -> &mut O { - &mut self.owner - } - /// Discards the reference and retrieves the owner. pub fn into_owner(self) -> O { self.owner From 05aa492ae12b83e4fe3cb6ca9e42228fca695105 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Mon, 18 Jan 2021 19:35:40 +0100 Subject: [PATCH 4/4] Adjust Debug implementation after as_owner was removed from OwningRefMut --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7e25ff9..0bdad83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1060,8 +1060,7 @@ impl<'t, O, T: ?Sized> Debug for OwningRefMut<'t, O, T> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, - "OwningRefMut {{ owner: {:?}, reference: {:?} }}", - self.as_owner(), + "OwningRefMut {{ owner: _, reference: {:?} }}", &**self) } }