@@ -264,130 +264,133 @@ where
264264 && let hir:: OpaqueTyOrigin :: FnReturn ( parent_def_id) = opaque. origin
265265 && parent_def_id == self . parent_def_id
266266 {
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-
334267 let opaque_span = self . tcx . def_span ( opaque_def_id) ;
335268 let new_capture_rules =
336269 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.
340270 if !new_capture_rules
341271 && !opaque. bounds . iter ( ) . any ( |bound| matches ! ( bound, hir:: GenericBound :: Use ( ..) ) )
342- && !uncaptured_args. is_empty ( )
343272 {
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 ( ) ) ;
365292 }
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 ( ) ;
369303
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+ } )
373337 . 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+ } ;
374370
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+ }
386388 }
389+
387390 // Otherwise, if we are edition 2024, have `use<>` syntax, and
388391 // have no uncaptured args, then we should warn to the user that
389392 // it's redundant to capture all args explicitly.
390- else if new_capture_rules
393+ if new_capture_rules
391394 && let Some ( ( captured_args, capturing_span) ) =
392395 opaque. bounds . iter ( ) . find_map ( |bound| match * bound {
393396 hir:: GenericBound :: Use ( a, s) => Some ( ( a, s) ) ,
0 commit comments