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