@@ -5,7 +5,10 @@ use clippy_utils::{def_path_def_ids, fn_def_id, is_lint_allowed};
55use rustc_data_structures:: fx:: FxHashMap ;
66use rustc_errors:: { Applicability , Diagnostic } ;
77use rustc_hir:: def_id:: DefId ;
8- use rustc_hir:: { Body , CoroutineKind , Expr , ExprKind } ;
8+ use rustc_hir:: {
9+ Body , BodyId , Closure , ClosureKind , CoroutineDesugaring , CoroutineKind , Expr , ExprKind , ImplItem , ImplItemKind ,
10+ Item , ItemKind , Node , TraitItem , TraitItemKind ,
11+ } ;
912use rustc_lint:: { LateContext , LateLintPass } ;
1013use rustc_session:: impl_lint_pass;
1114use rustc_span:: Span ;
@@ -40,7 +43,7 @@ declare_clippy_lint! {
4043 /// ```
4144 #[ clippy:: version = "1.74.0" ]
4245 pub UNNECESSARY_BLOCKING_OPS ,
43- nursery ,
46+ pedantic ,
4447 "blocking operations in an async context"
4548}
4649
@@ -108,8 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryBlockingOps {
108111 if is_lint_allowed ( cx, UNNECESSARY_BLOCKING_OPS , body. value . hir_id ) {
109112 return ;
110113 }
111-
112- if let Some ( CoroutineKind :: Async ( _) ) = body. coroutine_kind ( ) {
114+ if in_async_body ( cx, body. id ( ) ) {
113115 self . is_in_async = true ;
114116 }
115117 }
@@ -134,8 +136,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryBlockingOps {
134136 }
135137 }
136138
137- fn check_body_post ( & mut self , _ : & LateContext < ' tcx > , body : & ' tcx Body < ' tcx > ) {
138- if !matches ! ( body. coroutine_kind ( ) , Some ( CoroutineKind :: Async ( _ ) ) ) {
139+ fn check_body_post ( & mut self , cx : & LateContext < ' tcx > , body : & ' tcx Body < ' tcx > ) {
140+ if !in_async_body ( cx , body. id ( ) ) {
139141 self . is_in_async = false ;
140142 }
141143 }
@@ -153,3 +155,31 @@ fn make_suggestion(diag: &mut Diagnostic, cx: &LateContext<'_>, expr: &Expr<'_>,
153155 Applicability :: Unspecified ,
154156 ) ;
155157}
158+
159+ fn in_async_body ( cx : & LateContext < ' _ > , body_id : BodyId ) -> bool {
160+ let Some ( parent_node) = cx. tcx . hir ( ) . find_parent ( body_id. hir_id ) else {
161+ return false ;
162+ } ;
163+ match parent_node {
164+ Node :: Expr ( expr) => matches ! (
165+ expr. kind,
166+ ExprKind :: Closure ( Closure {
167+ kind: ClosureKind :: Coroutine ( CoroutineKind :: Desugared ( CoroutineDesugaring :: Async , _) ) ,
168+ ..
169+ } )
170+ ) ,
171+ Node :: Item ( Item {
172+ kind : ItemKind :: Fn ( fn_sig, ..) ,
173+ ..
174+ } )
175+ | Node :: ImplItem ( ImplItem {
176+ kind : ImplItemKind :: Fn ( fn_sig, _) ,
177+ ..
178+ } )
179+ | Node :: TraitItem ( TraitItem {
180+ kind : TraitItemKind :: Fn ( fn_sig, _) ,
181+ ..
182+ } ) => fn_sig. header . is_async ( ) ,
183+ _ => false ,
184+ }
185+ }
0 commit comments