Repository: tokio-rs/tokio
File: tokio/src/sync/rwlock/owned_write_guard.rs (Rust)

Code before:
    /// Makes a new [`OwnedRwLockReadGuard`] for a component of the locked data.
    ///
    /// This operation cannot fail as the `OwnedRwLockWriteGuard` passed in already
    /// locked the data.
    ///
    /// This is an associated function that needs to be used as
    /// `OwnedRwLockWriteGuard::downgrade_map(..)`. A method would interfere with methods of
    /// the same name on the contents of the locked data.
    ///
    /// Inside of `f`, you retain exclusive access to the data, despite only being given a `&T`. Handing out a
    /// `&mut T` would result in unsoundness, as you could use interior mutability.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use tokio::sync::{RwLock, OwnedRwLockWriteGuard};
    ///
    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    /// struct Foo(u32);
    ///
    /// # #[tokio::main]
    /// # async fn main() {
    /// let lock = Arc::new(RwLock::new(Foo(1)));
    ///
    /// let mapped = OwnedRwLockWriteGuard::downgrade_map(Arc::clone(&lock).write_owned().await, |f| &f.0);
    /// let foo = lock.read_owned().await;
    /// assert_eq!(foo.0, *mapped);
    /// # }
    /// ```
    #[inline]
    pub fn downgrade_map<F, U: ?Sized>(this: Self, f: F) -> OwnedRwLockReadGuard<T, U>
    where
        F: FnOnce(&T) -> &U,
    {
        let data = f(&*this) as *const U;
        let this = this.skip_drop();
        let guard = OwnedRwLockReadGuard {
            lock: this.lock,
            data,
            _p: PhantomData,
            #[cfg(all(tokio_unstable, feature = "tracing"))]
            resource_span: this.resource_span,
        };

        // Release all but one of the permits held by the write guard
        let to_release = (this.permits_acquired - 1) as usize;
        guard.lock.s.release(to_release);

        #[cfg(all(tokio_unstable, feature = "tracing"))]
        guard.resource_span.in_scope(|| {

Review comment (refactor):
Could you split this line? It's hard to see what's going on here from the docs page.
```suggestion
    /// let guard = Arc::clone(&lock).write_owned().await;
    /// let mapped = OwnedRwLockWriteGuard::downgrade_map(guard, |f| &f.0);
```

Code after:
    /// Makes a new [`OwnedRwLockReadGuard`] for a component of the locked data.
    ///
    /// This operation cannot fail as the `OwnedRwLockWriteGuard` passed in already
    /// locked the data.
    ///
    /// This is an associated function that needs to be used as
    /// `OwnedRwLockWriteGuard::downgrade_map(..)`. A method would interfere with methods of
    /// the same name on the contents of the locked data.
    ///
    /// Inside of `f`, you retain exclusive access to the data, despite only being given a `&T`. Handing out a
    /// `&mut T` would result in unsoundness, as you could use interior mutability.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use tokio::sync::{RwLock, OwnedRwLockWriteGuard};
    ///
    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    /// struct Foo(u32);
    ///
    /// # #[tokio::main]
    /// # async fn main() {
    /// let lock = Arc::new(RwLock::new(Foo(1)));
    ///
    /// let guard = Arc::clone(&lock).write_owned().await;
    /// let mapped = OwnedRwLockWriteGuard::downgrade_map(guard, |f| &f.0);
    /// let foo = lock.read_owned().await;
    /// assert_eq!(foo.0, *mapped);
    /// # }
    /// ```
    #[inline]
    pub fn downgrade_map<F, U: ?Sized>(this: Self, f: F) -> OwnedRwLockReadGuard<T, U>
    where
        F: FnOnce(&T) -> &U,
    {
        let data = f(&*this) as *const U;
        let this = this.skip_drop();
        let guard = OwnedRwLockReadGuard {
            lock: this.lock,
            data,
            _p: PhantomData,
            #[cfg(all(tokio_unstable, feature = "tracing"))]
            resource_span: this.resource_span,
        };

        // Release all but one of the permits held by the write guard
        let to_release = (this.permits_acquired - 1) as usize;
        guard.lock.s.release(to_release);

        #[cfg(all(tokio_unstable, feature = "tracing"))]