@@ -689,6 +689,13 @@ struct DiagMetadata<'ast> {
689689 current_elision_failures : Vec < MissingLifetime > ,
690690}
691691
692+ #[ derive( Debug ) ]
693+ struct ResolvedNestedElisionTarget {
694+ segment_id : NodeId ,
695+ elided_lifetime_span : Span ,
696+ diagnostic : lint:: BuiltinLintDiag ,
697+ }
698+
692699struct LateResolutionVisitor < ' a , ' ast , ' ra , ' tcx > {
693700 r : & ' a mut Resolver < ' ra , ' tcx > ,
694701
@@ -729,6 +736,9 @@ struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
729736
730737 /// Count the number of places a lifetime is used.
731738 lifetime_uses : FxHashMap < LocalDefId , LifetimeUseSet > ,
739+
740+ /// Track which types participated in lifetime elision
741+ resolved_lifetime_elisions : Vec < ResolvedNestedElisionTarget > ,
732742}
733743
734744/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -1433,6 +1443,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
14331443 // errors at module scope should always be reported
14341444 in_func_body : false ,
14351445 lifetime_uses : Default :: default ( ) ,
1446+ resolved_lifetime_elisions : Vec :: new ( ) ,
14361447 }
14371448 }
14381449
@@ -2116,17 +2127,16 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
21162127 }
21172128
21182129 if should_lint {
2119- self . r . lint_buffer . buffer_lint (
2120- lint:: builtin:: ELIDED_LIFETIMES_IN_PATHS ,
2130+ self . resolved_lifetime_elisions . push ( ResolvedNestedElisionTarget {
21212131 segment_id,
21222132 elided_lifetime_span,
2123- lint:: BuiltinLintDiag :: ElidedLifetimesInPaths (
2133+ diagnostic : lint:: BuiltinLintDiag :: ElidedLifetimesInPaths (
21242134 expected_lifetimes,
21252135 path_span,
21262136 !segment. has_generic_args ,
21272137 elided_lifetime_span,
21282138 ) ,
2129- ) ;
2139+ } ) ;
21302140 }
21312141 }
21322142 }
@@ -2211,24 +2221,46 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22112221 inputs : impl Iterator < Item = ( Option < & ' ast Pat > , & ' ast Ty ) > + Clone ,
22122222 output_ty : & ' ast FnRetTy ,
22132223 ) {
2224+ let outer_resolved_lifetime_elisions = take ( & mut self . resolved_lifetime_elisions ) ;
2225+
22142226 // Add each argument to the rib.
22152227 let elision_lifetime = self . resolve_fn_params ( has_self, inputs) ;
22162228 debug ! ( ?elision_lifetime) ;
2229+ let param_resolved_lifetime_elisions = take ( & mut self . resolved_lifetime_elisions ) ;
22172230
22182231 let outer_failures = take ( & mut self . diag_metadata . current_elision_failures ) ;
2232+
22192233 let output_rib = if let Ok ( res) = elision_lifetime. as_ref ( ) {
22202234 self . r . lifetime_elision_allowed . insert ( fn_id) ;
22212235 LifetimeRibKind :: Elided ( * res)
22222236 } else {
22232237 LifetimeRibKind :: ElisionFailure
22242238 } ;
22252239 self . with_lifetime_rib ( output_rib, |this| visit:: walk_fn_ret_ty ( this, output_ty) ) ;
2240+
22262241 let elision_failures =
22272242 replace ( & mut self . diag_metadata . current_elision_failures , outer_failures) ;
22282243 if !elision_failures. is_empty ( ) {
22292244 let Err ( failure_info) = elision_lifetime else { bug ! ( ) } ;
22302245 self . report_missing_lifetime_specifiers ( elision_failures, Some ( failure_info) ) ;
22312246 }
2247+
2248+ let output_resolved_lifetime_elisions =
2249+ replace ( & mut self . resolved_lifetime_elisions , outer_resolved_lifetime_elisions) ;
2250+
2251+ let resolved_lifetime_elisions =
2252+ param_resolved_lifetime_elisions. into_iter ( ) . chain ( output_resolved_lifetime_elisions) ;
2253+
2254+ for re in resolved_lifetime_elisions {
2255+ let ResolvedNestedElisionTarget { segment_id, elided_lifetime_span, diagnostic } = re;
2256+
2257+ self . r . lint_buffer . buffer_lint (
2258+ lint:: builtin:: ELIDED_LIFETIMES_IN_PATHS ,
2259+ segment_id,
2260+ elided_lifetime_span,
2261+ diagnostic,
2262+ ) ;
2263+ }
22322264 }
22332265
22342266 /// Resolve inside function parameters and parameter types.
0 commit comments