@@ -1760,10 +1760,29 @@ impl<'a, L: Ledger, Backend: WalletBackend<'a, L>> WalletSharedState<'a, L, Back
1760
1760
}
1761
1761
}
1762
1762
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
+
1763
1768
impl < ' a , L : ' static + Ledger , Backend : ' a + WalletBackend < ' a , L > + Send + Sync >
1764
1769
Wallet < ' a , Backend , L >
1765
1770
{
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 > {
1767
1786
let state = backend. load ( ) . await ?;
1768
1787
let mut events = backend. subscribe ( state. txn_state . now , None ) . await ;
1769
1788
let mut key_scans = vec ! [ ] ;
0 commit comments