1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! This crate provides [`SendFuture::send`] workaround for compiler bug
//! [https://github.com/rust-lang/rust/issues/96865](https://github.com/rust-lang/rust/issues/96865)
//!
//! See documentation of [`SendFuture`] trait for example usage
/// This trait is used as a workaround for compiler bug
/// [https://github.com/rust-lang/rust/issues/96865](https://github.com/rust-lang/rust/issues/96865)
///
/// Compilation of code calling async methods defined using `impl` syntax within [`Send`] async functions
/// may fail with hard-to-debug errors.
///
/// The following fails to compile with rustc 1.78.0:
///
/// ```compile_fail
/// trait X {
/// fn test<Y>(&self, x: impl AsRef<[Y]>) -> impl core::future::Future<Output = ()> + Send
/// where
/// Y: AsRef<str>;
/// }
/// fn call_test(x: impl X + Send + Sync) -> impl core::future::Future<Output = ()> + Send {
/// async move { x.test(["test"]).await }
/// }
/// ```
///
/// ```text
/// error: implementation of `AsRef` is not general enough
/// --> src/lib.rs:66:9
/// |
/// 66 | async move { x.test(["test"]).await }
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `AsRef` is not general enough
/// |
/// = note: `[&'0 str; 1]` must implement `AsRef<[&'1 str]>`, for any two lifetimes `'0` and `'1`...
/// = note: ...but it actually implements `AsRef<[&str]>`
/// ```
///
/// The fix is to call [`send`](SendFuture::send) provided by this trait on the future before awaiting:
/// ```
/// use send_future::SendFuture as _;
///
/// trait X {
/// fn test<Y>(&self, x: impl AsRef<[Y]>) -> impl core::future::Future<Output = ()> + Send
/// where
/// Y: AsRef<str>;
/// }
/// fn call_test(x: impl X + Send + Sync) -> impl core::future::Future<Output = ()> + Send {
/// async move { x.test(["test"]).send().await }
/// }
/// ```