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

``