@@ -267,130 +267,133 @@ where
267267 && let hir:: OpaqueTyOrigin :: FnReturn ( parent_def_id) = opaque. origin
268268 && parent_def_id == self . parent_def_id
269269 {
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-
337270 let opaque_span = self . tcx . def_span ( opaque_def_id) ;
338271 let new_capture_rules =
339272 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.
343273 if !new_capture_rules
344274 && !opaque. bounds . iter ( ) . any ( |bound| matches ! ( bound, hir:: GenericBound :: Use ( ..) ) )
345- && !uncaptured_args. is_empty ( )
346275 {
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 ( ) ) ;
368295 }
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 ( ) ;
372306
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+ } )
376340 . 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+ } ;
377373
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+ }
389391 }
392+
390393 // Otherwise, if we are edition 2024, have `use<>` syntax, and
391394 // have no uncaptured args, then we should warn to the user that
392395 // it's redundant to capture all args explicitly.
393- else if new_capture_rules
396+ if new_capture_rules
394397 && let Some ( ( captured_args, capturing_span) ) =
395398 opaque. bounds . iter ( ) . find_map ( |bound| match * bound {
396399 hir:: GenericBound :: Use ( a, s) => Some ( ( a, s) ) ,
0 commit comments