Repository: tokio-rs/tokio
File: tokio-util/src/task/abort_on_drop.rs (Rust)

Code before:
/// tasks completion, and in exchange can be a concrete type.
///
///
/// [aborts]: tokio::task::JoinHandle::abort
#[must_use = "Dropping the handle aborts the task immediately"]
pub struct AbortOnDrop(AbortHandle);

impl Drop for AbortOnDrop {
    fn drop(&mut self) {
        self.0.abort()
    }
}

impl AbortOnDrop {
    /// Create an [`AbortOnDrop`] from a [`AbortHandle`].
    pub fn new(handle: AbortHandle) -> Self {
        Self(handle)
    }

    /// Abort the task associated with this handle,
    /// equivalent to [`AbortHandle::abort`].
    pub fn abort(&self) {
        self.0.abort()
    }

    /// Checks if the task associated with this handle is finished,
    /// equivalent to [`AbortHandle::is_finished`].
    pub fn is_finished(&self) -> bool {
        self.0.is_finished()
    }

    /// Cancels aborting on drop and returns the original [`AbortHandle`].
    pub fn detach(self) -> AbortHandle {
        // Avoid invoking `AbortOnDrop`'s `Drop` impl
        let this = ManuallyDrop::new(self);
        // SAFETY: `&this.0` is a reference, so it is certainly initialized, and
        // it won't be double-dropped because it's in a `ManuallyDrop`
        unsafe { std::ptr::read(&this.0) }
    }
}

impl std::fmt::Debug for AbortOnDrop {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("AbortOnDrop")
            .field("id", &self.0.id())
            .finish()
    }
}

#[cfg(test)]
mod tests {

Review comment (suggestion):
```suggestion
    #[inline]
    pub fn abort(&self) {
```

Code after:
///
/// Unlike [`AbortOnDropHandle`], [`AbortOnDrop`] cannot be `.await`ed for a result.
///
/// It has no generic parameter, making it suitable when you only need to keep
/// a task handle in a struct and do not care about the output.
///
/// [aborts]: tokio::task::AbortHandle::abort
#[must_use = "Dropping the handle aborts the task immediately"]
pub struct AbortOnDrop(AbortHandle);

impl Drop for AbortOnDrop {
    fn drop(&mut self) {
        self.abort()
    }
}

impl AbortOnDrop {
    /// Create an [`AbortOnDrop`] from a [`AbortHandle`].
    pub fn new(handle: AbortHandle) -> Self {
        Self(handle)
    }

    /// Abort the task associated with this handle,
    /// equivalent to [`AbortHandle::abort`].
    #[inline]
    pub fn abort(&self) {
        self.0.abort()
    }

    /// Checks if the task associated with this handle is finished,
    /// equivalent to [`AbortHandle::is_finished`].
    #[inline]
    pub fn is_finished(&self) -> bool {
        self.0.is_finished()
    }

    /// Cancels aborting on drop and returns the original [`AbortHandle`].
    pub fn detach(self) -> AbortHandle {
        // Avoid invoking `AbortOnDrop`'s `Drop` impl
        let this = ManuallyDrop::new(self);
        // SAFETY: `&this.0` is a reference, so it is certainly initialized, and
        // it won't be double-dropped because it's in a `ManuallyDrop`
        unsafe { std::ptr::read(&this.0) }
    }
}

impl std::fmt::Debug for AbortOnDrop {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("AbortOnDrop")
            .field("id", &self.0.id())
            .finish()