Skip to content

Unnecessary Box::pin() #201

Open
Open
@realcr

Description

@realcr

Some places in the code base use Box::pin(...) only to create a future that satisfies Pin requirements. One example from components/channeler/src/connect_pool.rs:

async fn conn_attempt<RA, C, ET>(
    friend_public_key: PublicKey,
    address: RA,
    mut client_connector: C,
    mut encrypt_transform: ET,
    canceler: oneshot::Receiver<()>,
) -> Option<RawConn>
where
    RA: Eq,
    C: FutTransform<Input = (RA, PublicKey), Output = Option<RawConn>> + Clone,
    ET: FutTransform<Input = (PublicKey, RawConn), Output = Option<RawConn>> + Clone,
{
    // TODO: How to remove this Box::pin?
    let connect_fut = Box::pin(async move {
        let raw_conn = await!(client_connector.transform((address, friend_public_key.clone())))?;
        await!(encrypt_transform.transform((friend_public_key.clone(), raw_conn)))
    });

    // We either finish connecting, or got canceled in the middle:
    select! {
        connect_fut = connect_fut.fuse() => connect_fut,
        _ = canceler.fuse() => None,
    }
}

Box::pin(...) is a runtime tradeoff we make only to satisfy the compiler. Is there a way to write this code without using Box::pin(...), and also without using unsafe tricks? It seems to me that we should be able to pin the future to the stack somehow, but I'm not sure if we are supposed to do this.

This is not high priority, but I was curious about this problem for a while. There are other places in the code that have the same problem, you can probably find them by searching for "Box::pin". (Note that there are some legitimate uses of Box::pin around the code too).

@pzmarzly : Do you think you can check this out?

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-LowquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions