Fill in prose to describe the async_fn_in_trait
lint · rust-lang/rust@afea0b4 (original) (raw)
`@@ -5,26 +5,86 @@ use rustc_hir as hir;
`
5
5
`use rustc_trait_selection::traits::error_reporting::suggestions::suggest_desugaring_async_fn_to_impl_future_in_trait;
`
6
6
``
7
7
`declare_lint! {
`
8
``
`-
/// TODO
`
``
8
`` +
/// The async_fn_in_trait
lint detects use of async fn
in the
``
``
9
`+
/// definition of a publicly-reachable trait.
`
9
10
`///
`
10
11
`/// ### Example
`
11
12
`///
`
12
13
```` /// ```rust
`13`
``
`-
/// fn foo<T: Drop>() {}
`
``
`14`
`+
/// # #![feature(async_fn_in_trait)]
`
``
`15`
`+
/// pub trait Trait {
`
``
`16`
`+
/// async fn method(&self);
`
``
`17`
`+
/// }
`
``
`18`
`+
/// # fn main() {}
`
`14`
`19`
```` /// ```
15
20
`///
`
16
21
`/// {{produces}}
`
17
22
`///
`
18
23
`/// ### Explanation
`
19
24
`///
`
20
``
`-
/// TODO
`
``
25
`` +
/// When async fn
is used in a trait definition, the trait does not
``
``
26
`` +
/// promise that the opaque [Future
] returned by the associated function
``
``
27
`` +
/// or method will implement any [auto traits] such as [Send
]. This may
``
``
28
`+
/// be surprising and may make the associated functions or methods on the
`
``
29
`+
/// trait less useful than intended. On traits exposed publicly from a
`
``
30
`+
/// crate, this may affect downstream crates whose authors cannot alter
`
``
31
`+
/// the trait definition.
`
``
32
`+
///
`
``
33
`+
/// For example, this code is invalid:
`
``
34
`+
///
`
``
35
/// ```rust,compile_fail
``
36
`+
/// # #![feature(async_fn_in_trait)]
`
``
37
`+
/// pub trait Trait {
`
``
38
`+
/// async fn method(&self) {}
`
``
39
`+
/// }
`
``
40
`+
///
`
``
41
`+
/// fn test<T: Trait>(x: T) {
`
``
42
`+
/// fn is_send<T: Send>(_: T) {}
`
``
43
`+
/// is_send(x.method()); // Not OK.
`
``
44
`+
/// }
`
``
45
/// ```
``
46
`+
///
`
``
47
`+
/// This lint exists to warn authors of publicly-reachable traits that
`
``
48
`` +
/// they may want to consider desugaring the async fn
to a normal fn
``
``
49
`` +
/// that returns an opaque impl Future<..> + Send
type.
``
``
50
`+
///
`
``
51
`+
/// For example, instead of:
`
``
52
`+
///
`
``
53
/// ```rust
``
54
`+
/// # #![feature(async_fn_in_trait)]
`
``
55
`+
/// pub trait Trait {
`
``
56
`+
/// async fn method(&self) {}
`
``
57
`+
/// }
`
``
58
/// ```
``
59
`+
///
`
``
60
`+
/// The author of the trait may want to write:
`
``
61
`+
///
`
``
62
`+
///
`
``
63
/// ```rust
``
64
`+
/// # #![feature(return_position_impl_trait_in_trait)]
`
``
65
`+
/// use core::future::Future;
`
``
66
`+
/// pub trait Trait {
`
``
67
`+
/// fn method(&self) -> impl Future<Output = ()> + Send { async {} }
`
``
68
`+
/// }
`
``
69
/// ```
``
70
`+
///
`
``
71
`+
/// Conversely, if the trait is used only locally, if only concrete types
`
``
72
`+
/// that implement the trait are used, or if the trait author otherwise
`
``
73
`+
/// does not care that the trait will not promise that the returned
`
``
74
`` +
/// [Future
] implements any [auto traits] such as [Send
], then the
``
``
75
`+
/// lint may be suppressed.
`
``
76
`+
///
`
``
77
`` +
/// [Future
]: https://doc.rust-lang.org/core/future/trait.Future.html
``
``
78
`` +
/// [Send
]: https://doc.rust-lang.org/core/marker/trait.Send.html
``
``
79
`+
/// [auto traits]: https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits
`
21
80
`pub ASYNC_FN_IN_TRAIT,
`
22
81
`Warn,
`
23
``
`-
"TODO"
`
``
82
`` +
"use of async fn
in definition of a publicly-reachable trait"
``
24
83
`}
`
25
84
``
26
85
`declare_lint_pass!(
`
27
``
`-
// TODO:
`
``
86
`` +
/// Lint for use of async fn
in the definition of a publicly-reachable
``
``
87
`+
/// trait.
`
28
88
`AsyncFnInTrait => [ASYNC_FN_IN_TRAIT]
`
29
89
`);
`
30
90
``