Align RwLockWriteGuard fields with the other RwLock guards (+ cleanup) by connortsui20 · Pull Request #140018 · rust-lang/rust (original) (raw)

Tracking Issue: #138559

Relevant comment: #138559 (comment)

Summary

This PR does a few things as setup for the implementation of try_upgrade on RwLock. They are mostly cosmetic changes.

Changes

The only non-cosmetic change here is the last point, in which the fields of RwLockWriteGuard are different.

/// (For reference) pub struct RwLock<T: ?Sized> { inner: sys::RwLock, poison: poison::Flag, data: UnsafeCell, }

/// Before pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> { lock: &'a RwLock, poison: poison::Guard, }

/// After pub struct RwLockWriteGuard<'rwlock, T: ?Sized + 'rwlock> { /// A pointer to the data protected by the RwLock. NonNull is preferable over *mut T to /// allow for niche optimizations. /// Note that we use a pointer here instead of &'rwlock mut T to avoid noalias violations, /// because a RwLockWriteGuard instance only holds uniqueness until it drops, not for its /// whole scope. data: NonNull, /// NonNull is covariant over T, so we add a PhantomData<&'rwlock mut T> field below for /// the correct variance over T (invariance). _variance: PhantomData<&'rwlock mut T>, /// A reference back to the original (internal) lock. inner_lock: &'rwlock sys::RwLock, /// A reference to the original RwLock's poison state. poison_flag: &'rwlock poison::Flag, /// The poison guard. See the [poison] module for more information. poison_guard: poison::Guard, }

As a TLDR for #138559 (comment), if we want to convert a RwLockReadGuard into a RwLockWriteGuard safely (as we will need to for try_upgrade), I'm pretty sure we need to make the fields the same otherwise we have to do some nasty transmuting. Note it is very possible that I could be wrong on this.

Concerns

I do have a concern over the noalias comment that I essentially copied and pasted from the docs for MappedRwLockWriteGuard. Is it really true that making the data field NonNull here avoids noalias LLVM violations in the exclusive / unique setting? This description makes sense for the read variants of the guards, but I'm having trouble wrapping my head around the logic for the write variants.

I am also somewhat concerned because MutexGuard only stores a reference while MappedMutexGuard stores a pointer.

The only reason I have it here is because MappedRwLockWriteGuard was merged in #117107. CC'ing @zachs18 since he wrote that PR.