@@ -2,9 +2,9 @@ use clippy_utils::diagnostics::span_lint_and_then;
22use clippy_utils:: { match_def_path, paths} ;
33use rustc_data_structures:: fx:: FxHashMap ;
44use rustc_hir:: def_id:: DefId ;
5- use rustc_hir:: { AsyncGeneratorKind , Body , BodyId , GeneratorKind } ;
5+ use rustc_hir:: { AsyncGeneratorKind , Body , GeneratorKind } ;
66use rustc_lint:: { LateContext , LateLintPass } ;
7- use rustc_middle:: ty :: GeneratorInteriorTypeCause ;
7+ use rustc_middle:: mir :: GeneratorLayout ;
88use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
99use rustc_span:: { sym, Span } ;
1010
@@ -197,36 +197,43 @@ impl LateLintPass<'_> for AwaitHolding {
197197 fn check_body ( & mut self , cx : & LateContext < ' _ > , body : & ' _ Body < ' _ > ) {
198198 use AsyncGeneratorKind :: { Block , Closure , Fn } ;
199199 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+ }
209204 }
210205 }
211206}
212207
213208impl 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 ( ) {
216211 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+ } ;
217224 if is_mutex_guard ( cx, adt. did ( ) ) {
218225 span_lint_and_then (
219226 cx,
220227 AWAIT_HOLDING_LOCK ,
221- ty_cause. span ,
228+ ty_cause. source_info . span ,
222229 "this `MutexGuard` is held across an `await` point" ,
223230 |diag| {
224231 diag. help (
225232 "consider using an async-aware `Mutex` type or ensuring the \
226233 `MutexGuard` is dropped before calling await",
227234 ) ;
228235 diag. span_note (
229- ty_cause . scope_span . unwrap_or ( span ) ,
236+ await_points ( ) ,
230237 "these are all the `await` points this lock is held through" ,
231238 ) ;
232239 } ,
@@ -235,18 +242,18 @@ impl AwaitHolding {
235242 span_lint_and_then (
236243 cx,
237244 AWAIT_HOLDING_REFCELL_REF ,
238- ty_cause. span ,
245+ ty_cause. source_info . span ,
239246 "this `RefCell` reference is held across an `await` point" ,
240247 |diag| {
241248 diag. help ( "ensure the reference is dropped before calling `await`" ) ;
242249 diag. span_note (
243- ty_cause . scope_span . unwrap_or ( span ) ,
250+ await_points ( ) ,
244251 "these are all the `await` points this reference is held through" ,
245252 ) ;
246253 } ,
247254 ) ;
248255 } 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) ;
250257 }
251258 }
252259 }
0 commit comments