@@ -267,130 +267,133 @@ where
267
267
&& let hir:: OpaqueTyOrigin :: FnReturn ( parent_def_id) = opaque. origin
268
268
&& parent_def_id == self . parent_def_id
269
269
{
270
- // Compute the set of args that are captured by the opaque...
271
- let mut captured = FxIndexSet :: default ( ) ;
272
- let mut captured_regions = FxIndexSet :: default ( ) ;
273
- let variances = self . tcx . variances_of ( opaque_def_id) ;
274
- let mut current_def_id = Some ( opaque_def_id. to_def_id ( ) ) ;
275
- while let Some ( def_id) = current_def_id {
276
- let generics = self . tcx . generics_of ( def_id) ;
277
- for param in & generics. own_params {
278
- // A param is captured if it's invariant.
279
- if variances[ param. index as usize ] != ty:: Invariant {
280
- continue ;
281
- }
282
-
283
- let arg = opaque_ty. args [ param. index as usize ] ;
284
- // We need to turn all `ty::Param`/`ConstKind::Param` and
285
- // `ReEarlyParam`/`ReBound` into def ids.
286
- captured. insert ( extract_def_id_from_arg ( self . tcx , generics, arg) ) ;
287
-
288
- captured_regions. extend ( arg. as_region ( ) ) ;
289
- }
290
- current_def_id = generics. parent ;
291
- }
292
-
293
- // Compute the set of in scope params that are not captured. Get their spans,
294
- // since that's all we really care about them for emitting the diagnostic.
295
- let mut uncaptured_args: FxIndexSet < _ > = self
296
- . in_scope_parameters
297
- . iter ( )
298
- . filter ( |& ( def_id, _) | !captured. contains ( def_id) )
299
- . collect ( ) ;
300
-
301
- // These are args that we know are likely fine to "overcapture", since they can be
302
- // contravariantly shortened to one of the already-captured lifetimes that they
303
- // outlive.
304
- let covariant_long_args: FxIndexSet < _ > = uncaptured_args
305
- . iter ( )
306
- . copied ( )
307
- . filter ( |& ( def_id, kind) | {
308
- let Some ( ty:: Bivariant | ty:: Contravariant ) = self . variances . get ( def_id) else {
309
- return false ;
310
- } ;
311
- let DefKind :: LifetimeParam = self . tcx . def_kind ( def_id) else {
312
- return false ;
313
- } ;
314
- let uncaptured = match * kind {
315
- ParamKind :: Early ( name, index) => ty:: Region :: new_early_param (
316
- self . tcx ,
317
- ty:: EarlyParamRegion { name, index } ,
318
- ) ,
319
- ParamKind :: Free ( def_id, name) => ty:: Region :: new_late_param (
320
- self . tcx ,
321
- self . parent_def_id . to_def_id ( ) ,
322
- ty:: BoundRegionKind :: BrNamed ( def_id, name) ,
323
- ) ,
324
- ParamKind :: Late => return false ,
325
- } ;
326
- // Does this region outlive any captured region?
327
- captured_regions. iter ( ) . any ( |r| {
328
- self . outlives_env
329
- . free_region_map ( )
330
- . sub_free_regions ( self . tcx , * r, uncaptured)
331
- } )
332
- } )
333
- . collect ( ) ;
334
- // We don't care to warn on these args.
335
- uncaptured_args. retain ( |arg| !covariant_long_args. contains ( arg) ) ;
336
-
337
270
let opaque_span = self . tcx . def_span ( opaque_def_id) ;
338
271
let new_capture_rules =
339
272
opaque_span. at_least_rust_2024 ( ) || self . tcx . features ( ) . lifetime_capture_rules_2024 ;
340
-
341
- // If we have uncaptured args, and if the opaque doesn't already have
342
- // `use<>` syntax on it, and we're < edition 2024, then warn the user.
343
273
if !new_capture_rules
344
274
&& !opaque. bounds . iter ( ) . any ( |bound| matches ! ( bound, hir:: GenericBound :: Use ( ..) ) )
345
- && !uncaptured_args. is_empty ( )
346
275
{
347
- let suggestion = if let Ok ( snippet) =
348
- self . tcx . sess . source_map ( ) . span_to_snippet ( opaque_span)
349
- && snippet. starts_with ( "impl " )
350
- {
351
- let ( lifetimes, others) : ( Vec < _ > , Vec < _ > ) = captured
352
- . into_iter ( )
353
- . partition ( |def_id| self . tcx . def_kind ( * def_id) == DefKind :: LifetimeParam ) ;
354
- // Take all lifetime params first, then all others (ty/ct).
355
- let generics: Vec < _ > = lifetimes
356
- . into_iter ( )
357
- . chain ( others)
358
- . map ( |def_id| self . tcx . item_name ( def_id) . to_string ( ) )
359
- . collect ( ) ;
360
- // Make sure that we're not trying to name any APITs
361
- if generics. iter ( ) . all ( |name| !name. starts_with ( "impl " ) ) {
362
- Some ( (
363
- format ! ( " + use<{}>" , generics. join( ", " ) ) ,
364
- opaque_span. shrink_to_hi ( ) ,
365
- ) )
366
- } else {
367
- None
276
+ // Compute the set of args that are captured by the opaque...
277
+ let mut captured = FxIndexSet :: default ( ) ;
278
+ let mut captured_regions = FxIndexSet :: default ( ) ;
279
+ let variances = self . tcx . variances_of ( opaque_def_id) ;
280
+ let mut current_def_id = Some ( opaque_def_id. to_def_id ( ) ) ;
281
+ while let Some ( def_id) = current_def_id {
282
+ let generics = self . tcx . generics_of ( def_id) ;
283
+ for param in & generics. own_params {
284
+ // A param is captured if it's invariant.
285
+ if variances[ param. index as usize ] != ty:: Invariant {
286
+ continue ;
287
+ }
288
+
289
+ let arg = opaque_ty. args [ param. index as usize ] ;
290
+ // We need to turn all `ty::Param`/`ConstKind::Param` and
291
+ // `ReEarlyParam`/`ReBound` into def ids.
292
+ captured. insert ( extract_def_id_from_arg ( self . tcx , generics, arg) ) ;
293
+
294
+ captured_regions. extend ( arg. as_region ( ) ) ;
368
295
}
369
- } else {
370
- None
371
- } ;
296
+ current_def_id = generics. parent ;
297
+ }
298
+
299
+ // Compute the set of in scope params that are not captured. Get their spans,
300
+ // since that's all we really care about them for emitting the diagnostic.
301
+ let mut uncaptured_args: FxIndexSet < _ > = self
302
+ . in_scope_parameters
303
+ . iter ( )
304
+ . filter ( |& ( def_id, _) | !captured. contains ( def_id) )
305
+ . collect ( ) ;
372
306
373
- let uncaptured_spans: Vec < _ > = uncaptured_args
374
- . into_iter ( )
375
- . map ( |( def_id, _) | self . tcx . def_span ( def_id) )
307
+ // These are args that we know are likely fine to "overcapture", since they can be
308
+ // contravariantly shortened to one of the already-captured lifetimes that they
309
+ // outlive.
310
+ let covariant_long_args: FxIndexSet < _ > = uncaptured_args
311
+ . iter ( )
312
+ . copied ( )
313
+ . filter ( |& ( def_id, kind) | {
314
+ let Some ( ty:: Bivariant | ty:: Contravariant ) = self . variances . get ( def_id)
315
+ else {
316
+ return false ;
317
+ } ;
318
+ let DefKind :: LifetimeParam = self . tcx . def_kind ( def_id) else {
319
+ return false ;
320
+ } ;
321
+ let uncaptured = match * kind {
322
+ ParamKind :: Early ( name, index) => ty:: Region :: new_early_param (
323
+ self . tcx ,
324
+ ty:: EarlyParamRegion { name, index } ,
325
+ ) ,
326
+ ParamKind :: Free ( def_id, name) => ty:: Region :: new_late_param (
327
+ self . tcx ,
328
+ self . parent_def_id . to_def_id ( ) ,
329
+ ty:: BoundRegionKind :: BrNamed ( def_id, name) ,
330
+ ) ,
331
+ ParamKind :: Late => return false ,
332
+ } ;
333
+ // Does this region outlive any captured region?
334
+ captured_regions. iter ( ) . any ( |r| {
335
+ self . outlives_env
336
+ . free_region_map ( )
337
+ . sub_free_regions ( self . tcx , * r, uncaptured)
338
+ } )
339
+ } )
376
340
. collect ( ) ;
341
+ // We don't care to warn on these args.
342
+ uncaptured_args. retain ( |arg| !covariant_long_args. contains ( arg) ) ;
343
+
344
+ // If we have uncaptured args, and if the opaque doesn't already have
345
+ // `use<>` syntax on it, and we're < edition 2024, then warn the user.
346
+ if !uncaptured_args. is_empty ( ) {
347
+ let suggestion = if let Ok ( snippet) =
348
+ self . tcx . sess . source_map ( ) . span_to_snippet ( opaque_span)
349
+ && snippet. starts_with ( "impl " )
350
+ {
351
+ let ( lifetimes, others) : ( Vec < _ > , Vec < _ > ) =
352
+ captured. into_iter ( ) . partition ( |def_id| {
353
+ self . tcx . def_kind ( * def_id) == DefKind :: LifetimeParam
354
+ } ) ;
355
+ // Take all lifetime params first, then all others (ty/ct).
356
+ let generics: Vec < _ > = lifetimes
357
+ . into_iter ( )
358
+ . chain ( others)
359
+ . map ( |def_id| self . tcx . item_name ( def_id) . to_string ( ) )
360
+ . collect ( ) ;
361
+ // Make sure that we're not trying to name any APITs
362
+ if generics. iter ( ) . all ( |name| !name. starts_with ( "impl " ) ) {
363
+ Some ( (
364
+ format ! ( " + use<{}>" , generics. join( ", " ) ) ,
365
+ opaque_span. shrink_to_hi ( ) ,
366
+ ) )
367
+ } else {
368
+ None
369
+ }
370
+ } else {
371
+ None
372
+ } ;
377
373
378
- self . tcx . emit_node_span_lint (
379
- IMPL_TRAIT_OVERCAPTURES ,
380
- self . tcx . local_def_id_to_hir_id ( opaque_def_id) ,
381
- opaque_span,
382
- ImplTraitOvercapturesLint {
383
- self_ty : t,
384
- num_captured : uncaptured_spans. len ( ) ,
385
- uncaptured_spans,
386
- suggestion,
387
- } ,
388
- ) ;
374
+ let uncaptured_spans: Vec < _ > = uncaptured_args
375
+ . into_iter ( )
376
+ . map ( |( def_id, _) | self . tcx . def_span ( def_id) )
377
+ . collect ( ) ;
378
+
379
+ self . tcx . emit_node_span_lint (
380
+ IMPL_TRAIT_OVERCAPTURES ,
381
+ self . tcx . local_def_id_to_hir_id ( opaque_def_id) ,
382
+ opaque_span,
383
+ ImplTraitOvercapturesLint {
384
+ self_ty : t,
385
+ num_captured : uncaptured_spans. len ( ) ,
386
+ uncaptured_spans,
387
+ suggestion,
388
+ } ,
389
+ ) ;
390
+ }
389
391
}
392
+
390
393
// Otherwise, if we are edition 2024, have `use<>` syntax, and
391
394
// have no uncaptured args, then we should warn to the user that
392
395
// it's redundant to capture all args explicitly.
393
- else if new_capture_rules
396
+ if new_capture_rules
394
397
&& let Some ( ( captured_args, capturing_span) ) =
395
398
opaque. bounds . iter ( ) . find_map ( |bound| match * bound {
396
399
hir:: GenericBound :: Use ( a, s) => Some ( ( a, s) ) ,
0 commit comments