Skip to content

clippy 1.99.0 double_must_use fails on async_trait-generated Blob trait #2784

Description

@fnando

Rust 1.99.0 ships a new clippy::double_must_use lint that fails make check (and therefore CI, e.g. #2783). The failure is in cmd/crates/stellar-ledger/src/signer.rs:

error: this function has a `#[must_use]` attribute with no message, but returns a type already considered as `#[must_use]`
 --> cmd/crates/stellar-ledger/src/signer.rs:1:28
  = note: the return type is pinned boxed `std::future::Future` trait object
  = note: `-D clippy::double-must-use` implied by `-D clippy::all`
  = note: this error originates in the attribute macro `async_trait::async_trait`

Cause

The #[async_trait::async_trait] macro on the Blob trait expands each async fn to a method that both (a) carries an explicit #[must_use] and (b) returns Pin<Box<dyn Future + Send>>, which clippy 1.99.0 now treats as already #[must_use]. The two together trip double_must_use. This is macro-generated code we do not control, so the lint is effectively a false positive for async-trait (already on the latest 0.1.89).

Options

  1. Suppress narrowly: add #[allow(clippy::double_must_use)] to the Blob trait. Smallest change, but hides the lint for that trait.
  2. Drop async_trait for native async-fn-in-trait (stable since 1.75). Blob is never used as dyn Blob (only as a bound and for method calls), so it can become:
use std::future::Future;

pub trait Blob {
    type Key: Send;
    type Error;
    fn get_public_key(
        &self,
        key: &Self::Key,
    ) -> impl Future<Output = Result<stellar_strkey::ed25519::PublicKey, Self::Error>> + Send;
    fn sign_blob(
        &self,
        key: &Self::Key,
        blob: &[u8],
    ) -> impl Future<Output = Result<Vec<u8>, Self::Error>> + Send;
}

with the #[async_trait::async_trait] attribute removed from the impl Blob for LedgerSigner<T> block in cmd/crates/stellar-ledger/src/lib.rs (the async fn bodies stay as-is). The explicit + Send return bound preserves the current Send semantics. This removes the lint-triggering macro entirely and is the modern idiom.

Note: the same crate still uses #[async_trait] in emulator_test_support/http_transport.rs for a different trait, which may hit the same lint once those feature-gated targets compile.

Impact

make check / CI is red for anyone on Rust 1.99.0 until this is addressed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    • Status
      Backlog (Not Ready)

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions