Skip to content
This repository was archived by the owner on Jan 15, 2024. It is now read-only.

Commit 3ee52f3

Browse files
committed
Add a workaround for rust-lang/rust#89657, which effects Wallet::new.
1 parent e1cd170 commit 3ee52f3

File tree

1 file changed

+20
-1
lines changed
  • zerok/zerok_lib/src/wallet

1 file changed

+20
-1
lines changed

zerok/zerok_lib/src/wallet/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1760,10 +1760,29 @@ impl<'a, L: Ledger, Backend: WalletBackend<'a, L>> WalletSharedState<'a, L, Back
17601760
}
17611761
}
17621762

1763+
// Fun fact: replacing `std::pin::Pin` with `Pin` and adding `use std::pin::Pin` causes the compiler
1764+
// to panic where this type alias is used in `Wallet::new`. As a result, the type alias `BoxFuture`
1765+
// from `futures::future` does not work, so we define our own.
1766+
type BoxFuture<'a, T> = std::pin::Pin<Box<dyn Future<Output = T> + Send + 'a>>;
1767+
17631768
impl<'a, L: 'static + Ledger, Backend: 'a + WalletBackend<'a, L> + Send + Sync>
17641769
Wallet<'a, Backend, L>
17651770
{
1766-
pub async fn new(mut backend: Backend) -> Result<Wallet<'a, Backend, L>, WalletError> {
1771+
// This function suffers from github.com/rust-lang/rust/issues/89657, in which, if we define it
1772+
// as an async function, the compiler loses track of the fact that the resulting opaque Future
1773+
// implements Send, even though it does. Unfortunately, the workaround used for some other
1774+
// functions in this module (c.f. `submit_elaborated_transaction`) where we manually desugar the
1775+
// function signature to explicitly return `impl Future + Send` triggers a separate and possibly
1776+
// unrelated compiler bug, which results in a panic during compilation.
1777+
//
1778+
// Fortunately, there is a different workaround which does work. The idea is the same: to
1779+
// manually write out the opaque return type so that we can explicitly add the `Send` bound. The
1780+
// difference is that we use dynamic type erasure (Pin<Box<dyn Future>>) instead of static type
1781+
// erasure. I don't know why this doesn't crash the compiler, but it doesn't.
1782+
pub fn new(backend: Backend) -> BoxFuture<'a, Result<Wallet<'a, Backend, L>, WalletError>> {
1783+
Box::pin(async move { Self::new_impl(backend).await })
1784+
}
1785+
async fn new_impl(mut backend: Backend) -> Result<Wallet<'a, Backend, L>, WalletError> {
17671786
let state = backend.load().await?;
17681787
let mut events = backend.subscribe(state.txn_state.now, None).await;
17691788
let mut key_scans = vec![];

0 commit comments

Comments
 (0)