@@ -45,50 +45,72 @@ declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
45
45
46
46
impl < ' tcx > LateLintPass < ' tcx > for AsyncYieldsAsync {
47
47
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
48
- // For functions, with explicitly defined types, don't warn.
49
- // XXXkhuey maybe we should?
50
- if let ExprKind :: Closure ( Closure {
51
- kind :
52
- ClosureKind :: Coroutine ( CoroutineKind :: Desugared (
53
- CoroutineDesugaring :: Async ,
54
- CoroutineSource :: Block | CoroutineSource :: Closure ,
55
- ) ) ,
48
+ let ExprKind :: Closure ( Closure {
49
+ kind : ClosureKind :: Coroutine ( CoroutineKind :: Desugared ( CoroutineDesugaring :: Async , kind) ) ,
56
50
body : body_id,
57
51
..
58
52
} ) = expr. kind
59
- {
60
- if let Some ( future_trait_def_id) = cx. tcx . lang_items ( ) . future_trait ( ) {
61
- let typeck_results = cx. tcx . typeck_body ( * body_id) ;
62
- let body = cx. tcx . hir ( ) . body ( * body_id) ;
63
- let expr_ty = typeck_results. expr_ty ( body. value ) ;
53
+ else {
54
+ return ;
55
+ } ;
64
56
65
- if implements_trait ( cx, expr_ty, future_trait_def_id, & [ ] ) {
66
- let return_expr_span = match & body. value . kind {
67
- // XXXkhuey there has to be a better way.
68
- ExprKind :: Block ( block, _) => block. expr . map ( |e| e. span ) ,
69
- ExprKind :: Path ( QPath :: Resolved ( _, path) ) => Some ( path. span ) ,
70
- _ => None ,
71
- } ;
72
- if let Some ( return_expr_span) = return_expr_span {
73
- span_lint_hir_and_then (
74
- cx,
75
- ASYNC_YIELDS_ASYNC ,
76
- body. value . hir_id ,
57
+ let body_expr = match kind {
58
+ CoroutineSource :: Fn => {
59
+ // For functions, with explicitly defined types, don't warn.
60
+ // XXXkhuey maybe we should?
61
+ return ;
62
+ } ,
63
+ CoroutineSource :: Block => cx. tcx . hir ( ) . body ( * body_id) . value ,
64
+ CoroutineSource :: Closure => {
65
+ // Like `async fn`, async closures are wrapped in an additional block
66
+ // to move all of the closure's arguments into the future.
67
+
68
+ let async_closure_body = cx. tcx . hir ( ) . body ( * body_id) . value ;
69
+ let ExprKind :: Block ( block, _) = async_closure_body. kind else {
70
+ return ;
71
+ } ;
72
+ let Some ( block_expr) = block. expr else {
73
+ return ;
74
+ } ;
75
+ let ExprKind :: DropTemps ( body_expr) = block_expr. kind else {
76
+ return ;
77
+ } ;
78
+ body_expr
79
+ } ,
80
+ } ;
81
+
82
+ let Some ( future_trait_def_id) = cx. tcx . lang_items ( ) . future_trait ( ) else {
83
+ return ;
84
+ } ;
85
+
86
+ let typeck_results = cx. tcx . typeck_body ( * body_id) ;
87
+ let expr_ty = typeck_results. expr_ty ( body_expr) ;
88
+
89
+ if implements_trait ( cx, expr_ty, future_trait_def_id, & [ ] ) {
90
+ let return_expr_span = match & body_expr. kind {
91
+ // XXXkhuey there has to be a better way.
92
+ ExprKind :: Block ( block, _) => block. expr . map ( |e| e. span ) ,
93
+ ExprKind :: Path ( QPath :: Resolved ( _, path) ) => Some ( path. span ) ,
94
+ _ => None ,
95
+ } ;
96
+ if let Some ( return_expr_span) = return_expr_span {
97
+ span_lint_hir_and_then (
98
+ cx,
99
+ ASYNC_YIELDS_ASYNC ,
100
+ body_expr. hir_id ,
101
+ return_expr_span,
102
+ "an async construct yields a type which is itself awaitable" ,
103
+ |db| {
104
+ db. span_label ( body_expr. span , "outer async construct" ) ;
105
+ db. span_label ( return_expr_span, "awaitable value not awaited" ) ;
106
+ db. span_suggestion (
77
107
return_expr_span,
78
- "an async construct yields a type which is itself awaitable" ,
79
- |db| {
80
- db. span_label ( body. value . span , "outer async construct" ) ;
81
- db. span_label ( return_expr_span, "awaitable value not awaited" ) ;
82
- db. span_suggestion (
83
- return_expr_span,
84
- "consider awaiting this value" ,
85
- format ! ( "{}.await" , snippet( cx, return_expr_span, ".." ) ) ,
86
- Applicability :: MaybeIncorrect ,
87
- ) ;
88
- } ,
108
+ "consider awaiting this value" ,
109
+ format ! ( "{}.await" , snippet( cx, return_expr_span, ".." ) ) ,
110
+ Applicability :: MaybeIncorrect ,
89
111
) ;
90
- }
91
- }
112
+ } ,
113
+ ) ;
92
114
}
93
115
}
94
116
}
0 commit comments