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
- Suppress narrowly: add
#[allow(clippy::double_must_use)] to the Blob trait. Smallest change, but hides the lint for that trait.
- 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.
Rust 1.99.0 ships a new
clippy::double_must_uselint that failsmake check(and therefore CI, e.g. #2783). The failure is incmd/crates/stellar-ledger/src/signer.rs:Cause
The
#[async_trait::async_trait]macro on theBlobtrait expands eachasync fnto a method that both (a) carries an explicit#[must_use]and (b) returnsPin<Box<dyn Future + Send>>, which clippy 1.99.0 now treats as already#[must_use]. The two together tripdouble_must_use. This is macro-generated code we do not control, so the lint is effectively a false positive forasync-trait(already on the latest 0.1.89).Options
#[allow(clippy::double_must_use)]to theBlobtrait. Smallest change, but hides the lint for that trait.async_traitfor native async-fn-in-trait (stable since 1.75).Blobis never used asdyn Blob(only as a bound and for method calls), so it can become:with the
#[async_trait::async_trait]attribute removed from theimpl Blob for LedgerSigner<T>block incmd/crates/stellar-ledger/src/lib.rs(theasync fnbodies stay as-is). The explicit+ Sendreturn bound preserves the currentSendsemantics. This removes the lint-triggering macro entirely and is the modern idiom.Note: the same crate still uses
#[async_trait]inemulator_test_support/http_transport.rsfor 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.