@@ -2,9 +2,9 @@ use clippy_utils::diagnostics::span_lint_and_then;
2
2
use clippy_utils:: { match_def_path, paths} ;
3
3
use rustc_data_structures:: fx:: FxHashMap ;
4
4
use rustc_hir:: def_id:: DefId ;
5
- use rustc_hir:: { AsyncGeneratorKind , Body , BodyId , GeneratorKind } ;
5
+ use rustc_hir:: { AsyncGeneratorKind , Body , GeneratorKind } ;
6
6
use rustc_lint:: { LateContext , LateLintPass } ;
7
- use rustc_middle:: ty :: GeneratorInteriorTypeCause ;
7
+ use rustc_middle:: mir :: GeneratorLayout ;
8
8
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
9
9
use rustc_span:: { sym, Span } ;
10
10
@@ -197,36 +197,43 @@ impl LateLintPass<'_> for AwaitHolding {
197
197
fn check_body ( & mut self , cx : & LateContext < ' _ > , body : & ' _ Body < ' _ > ) {
198
198
use AsyncGeneratorKind :: { Block , Closure , Fn } ;
199
199
if let Some ( GeneratorKind :: Async ( Block | Closure | Fn ) ) = body. generator_kind {
200
- let body_id = BodyId {
201
- hir_id : body. value . hir_id ,
202
- } ;
203
- let typeck_results = cx. tcx . typeck_body ( body_id) ;
204
- self . check_interior_types (
205
- cx,
206
- typeck_results. generator_interior_types . as_ref ( ) . skip_binder ( ) ,
207
- body. value . span ,
208
- ) ;
200
+ let def_id = cx. tcx . hir ( ) . body_owner_def_id ( body. id ( ) ) ;
201
+ if let Some ( generator_layout) = cx. tcx . mir_generator_witnesses ( def_id) {
202
+ self . check_interior_types ( cx, generator_layout) ;
203
+ }
209
204
}
210
205
}
211
206
}
212
207
213
208
impl AwaitHolding {
214
- fn check_interior_types ( & self , cx : & LateContext < ' _ > , ty_causes : & [ GeneratorInteriorTypeCause < ' _ > ] , span : Span ) {
215
- for ty_cause in ty_causes {
209
+ fn check_interior_types ( & self , cx : & LateContext < ' _ > , generator : & GeneratorLayout < ' _ > ) {
210
+ for ( ty_index , ty_cause) in generator . field_tys . iter_enumerated ( ) {
216
211
if let rustc_middle:: ty:: Adt ( adt, _) = ty_cause. ty . kind ( ) {
212
+ let await_points = || {
213
+ generator
214
+ . variant_source_info
215
+ . iter_enumerated ( )
216
+ . filter_map ( |( variant, source_info) | {
217
+ generator. variant_fields [ variant]
218
+ . raw
219
+ . contains ( & ty_index)
220
+ . then_some ( source_info. span )
221
+ } )
222
+ . collect :: < Vec < _ > > ( )
223
+ } ;
217
224
if is_mutex_guard ( cx, adt. did ( ) ) {
218
225
span_lint_and_then (
219
226
cx,
220
227
AWAIT_HOLDING_LOCK ,
221
- ty_cause. span ,
228
+ ty_cause. source_info . span ,
222
229
"this `MutexGuard` is held across an `await` point" ,
223
230
|diag| {
224
231
diag. help (
225
232
"consider using an async-aware `Mutex` type or ensuring the \
226
233
`MutexGuard` is dropped before calling await",
227
234
) ;
228
235
diag. span_note (
229
- ty_cause . scope_span . unwrap_or ( span ) ,
236
+ await_points ( ) ,
230
237
"these are all the `await` points this lock is held through" ,
231
238
) ;
232
239
} ,
@@ -235,18 +242,18 @@ impl AwaitHolding {
235
242
span_lint_and_then (
236
243
cx,
237
244
AWAIT_HOLDING_REFCELL_REF ,
238
- ty_cause. span ,
245
+ ty_cause. source_info . span ,
239
246
"this `RefCell` reference is held across an `await` point" ,
240
247
|diag| {
241
248
diag. help ( "ensure the reference is dropped before calling `await`" ) ;
242
249
diag. span_note (
243
- ty_cause . scope_span . unwrap_or ( span ) ,
250
+ await_points ( ) ,
244
251
"these are all the `await` points this reference is held through" ,
245
252
) ;
246
253
} ,
247
254
) ;
248
255
} else if let Some ( disallowed) = self . def_ids . get ( & adt. did ( ) ) {
249
- emit_invalid_type ( cx, ty_cause. span , disallowed) ;
256
+ emit_invalid_type ( cx, ty_cause. source_info . span , disallowed) ;
250
257
}
251
258
}
252
259
}
0 commit comments