From e548a817c89f38516c5cfb1d55ff593f0105e946 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Sat, 2 Jan 2021 18:22:12 -0800 Subject: [PATCH 1/2] Remove T: Trace bound from GcCellRef This bound unnecessarily prohibited some valid uses of GcCellRef::map. Signed-off-by: Anders Kaseorg --- gc/src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gc/src/lib.rs b/gc/src/lib.rs index efc6e8b..159317c 100644 --- a/gc/src/lib.rs +++ b/gc/src/lib.rs @@ -657,12 +657,12 @@ unsafe impl Trace for GcCell { } /// A wrapper type for an immutably borrowed value from a `GcCell`. -pub struct GcCellRef<'a, T: Trace + ?Sized + 'static> { +pub struct GcCellRef<'a, T: ?Sized + 'static> { flags: &'a Cell, value: &'a T, } -impl<'a, T: Trace + ?Sized> GcCellRef<'a, T> { +impl<'a, T: ?Sized> GcCellRef<'a, T> { /// Makes a new `GcCellRef` from a component of the borrowed data. /// /// The `GcCell` is already immutably borrowed, so this cannot fail. @@ -684,7 +684,7 @@ impl<'a, T: Trace + ?Sized> GcCellRef<'a, T> { #[inline] pub fn map(orig: Self, f: F) -> GcCellRef<'a, U> where - U: Trace + ?Sized, + U: ?Sized, F: FnOnce(&T) -> &U, { let ret = GcCellRef { @@ -720,8 +720,8 @@ impl<'a, T: Trace + ?Sized> GcCellRef<'a, T> { #[inline] pub fn map_split(orig: Self, f: F) -> (GcCellRef<'a, U>, GcCellRef<'a, V>) where - U: Trace + ?Sized, - V: Trace + ?Sized, + U: ?Sized, + V: ?Sized, F: FnOnce(&T) -> (&U, &V), { let (a, b) = f(orig.value); @@ -747,7 +747,7 @@ impl<'a, T: Trace + ?Sized> GcCellRef<'a, T> { } } -impl<'a, T: Trace + ?Sized> Deref for GcCellRef<'a, T> { +impl<'a, T: ?Sized> Deref for GcCellRef<'a, T> { type Target = T; #[inline] @@ -756,20 +756,20 @@ impl<'a, T: Trace + ?Sized> Deref for GcCellRef<'a, T> { } } -impl<'a, T: Trace + ?Sized> Drop for GcCellRef<'a, T> { +impl<'a, T: ?Sized> Drop for GcCellRef<'a, T> { fn drop(&mut self) { debug_assert!(self.flags.get().borrowed() == BorrowState::Reading); self.flags.set(self.flags.get().sub_reading()); } } -impl<'a, T: Trace + ?Sized + Debug> Debug for GcCellRef<'a, T> { +impl<'a, T: ?Sized + Debug> Debug for GcCellRef<'a, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Debug::fmt(&**self, f) } } -impl<'a, T: Trace + ?Sized + Display> Display for GcCellRef<'a, T> { +impl<'a, T: ?Sized + Display> Display for GcCellRef<'a, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Display::fmt(&**self, f) } From 3df1a9efaf480830553ac40b078cf056c3ce0337 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Sat, 2 Jan 2021 18:28:31 -0800 Subject: [PATCH 2/2] Add GcCellRef::clone Signed-off-by: Anders Kaseorg --- gc/src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gc/src/lib.rs b/gc/src/lib.rs index 159317c..490faf1 100644 --- a/gc/src/lib.rs +++ b/gc/src/lib.rs @@ -663,6 +663,23 @@ pub struct GcCellRef<'a, T: ?Sized + 'static> { } impl<'a, T: ?Sized> GcCellRef<'a, T> { + /// Copies a `GcCellRef`. + /// + /// The `GcCell` is already immutably borrowed, so this cannot fail. + /// + /// This is an associated function that needs to be used as + /// `GcCellRef::clone(...)`. A `Clone` implementation or a method + /// would interfere with the use of `c.borrow().clone()` to clone + /// the contents of a `GcCell`. + #[inline] + pub fn clone(orig: &GcCellRef<'a, T>) -> GcCellRef<'a, T> { + orig.flags.set(orig.flags.get().add_reading()); + GcCellRef { + flags: orig.flags, + value: orig.value, + } + } + /// Makes a new `GcCellRef` from a component of the borrowed data. /// /// The `GcCell` is already immutably borrowed, so this cannot fail.