@@ -111,35 +111,47 @@ impl<'tcx> LateLintPass<'tcx> for LifetimeSyntax {
111111}
112112
113113fn check_fn_like < ' tcx > ( cx : & LateContext < ' tcx > , fd : & ' tcx hir:: FnDecl < ' tcx > ) {
114- let mut input_map = Default :: default ( ) ;
115- let mut output_map = Default :: default ( ) ;
116-
117- for input in fd. inputs {
118- LifetimeInfoCollector :: collect ( input, & mut input_map) ;
114+ if fd. inputs . is_empty ( ) {
115+ return ;
119116 }
117+ let hir:: FnRetTy :: Return ( output) = fd. output else {
118+ return ;
119+ } ;
120120
121- if let hir:: FnRetTy :: Return ( output) = fd. output {
122- LifetimeInfoCollector :: collect ( output, & mut output_map) ;
123- }
121+ let mut map: FxIndexMap < hir:: LifetimeKind , LifetimeGroup < ' _ > > = FxIndexMap :: default ( ) ;
124122
125- report_mismatches ( cx, & input_map, & output_map) ;
126- }
123+ LifetimeInfoCollector :: collect ( output, |info| {
124+ let group = map. entry ( info. lifetime . kind ) . or_default ( ) ;
125+ group. outputs . push ( info) ;
126+ } ) ;
127+ if map. is_empty ( ) {
128+ return ;
129+ }
127130
128- #[ instrument( skip_all) ]
129- fn report_mismatches < ' tcx > (
130- cx : & LateContext < ' tcx > ,
131- inputs : & LifetimeInfoMap < ' tcx > ,
132- outputs : & LifetimeInfoMap < ' tcx > ,
133- ) {
134- for ( resolved_lifetime, output_info) in outputs {
135- if let Some ( input_info) = inputs. get ( resolved_lifetime) {
136- if !lifetimes_use_matched_syntax ( input_info, output_info) {
137- emit_mismatch_diagnostic ( cx, input_info, output_info) ;
131+ for input in fd. inputs {
132+ LifetimeInfoCollector :: collect ( input, |info| {
133+ if let Some ( group) = map. get_mut ( & info. lifetime . kind ) {
134+ group. inputs . push ( info) ;
138135 }
136+ } ) ;
137+ }
138+
139+ for LifetimeGroup { ref inputs, ref outputs } in map. into_values ( ) {
140+ if inputs. is_empty ( ) {
141+ continue ;
142+ }
143+ if !lifetimes_use_matched_syntax ( inputs, outputs) {
144+ emit_mismatch_diagnostic ( cx, inputs, outputs) ;
139145 }
140146 }
141147}
142148
149+ #[ derive( Default ) ]
150+ struct LifetimeGroup < ' tcx > {
151+ inputs : Vec < Info < ' tcx > > ,
152+ outputs : Vec < Info < ' tcx > > ,
153+ }
154+
143155#[ derive( Debug , Copy , Clone , PartialEq ) ]
144156enum LifetimeSyntaxCategory {
145157 Hidden ,
@@ -547,27 +559,31 @@ impl<'tcx> Info<'tcx> {
547559 }
548560}
549561
550- type LifetimeInfoMap < ' tcx > = FxIndexMap < & ' tcx hir:: LifetimeKind , Vec < Info < ' tcx > > > ;
551-
552- struct LifetimeInfoCollector < ' a , ' tcx > {
553- map : & ' a mut LifetimeInfoMap < ' tcx > ,
562+ struct LifetimeInfoCollector < ' tcx , F > {
563+ info_func : F ,
554564 ty : & ' tcx hir:: Ty < ' tcx > ,
555565}
556566
557- impl < ' a , ' tcx > LifetimeInfoCollector < ' a , ' tcx > {
558- fn collect ( ty : & ' tcx hir:: Ty < ' tcx > , map : & ' a mut LifetimeInfoMap < ' tcx > ) {
559- let mut this = Self { map, ty } ;
567+ impl < ' tcx , F > LifetimeInfoCollector < ' tcx , F >
568+ where
569+ F : FnMut ( Info < ' tcx > ) ,
570+ {
571+ fn collect ( ty : & ' tcx hir:: Ty < ' tcx > , info_func : F ) {
572+ let mut this = Self { info_func, ty } ;
560573
561574 intravisit:: walk_unambig_ty ( & mut this, ty) ;
562575 }
563576}
564577
565- impl < ' a , ' tcx > Visitor < ' tcx > for LifetimeInfoCollector < ' a , ' tcx > {
578+ impl < ' tcx , F > Visitor < ' tcx > for LifetimeInfoCollector < ' tcx , F >
579+ where
580+ F : FnMut ( Info < ' tcx > ) ,
581+ {
566582 #[ instrument( skip( self ) ) ]
567583 fn visit_lifetime ( & mut self , lifetime : & ' tcx hir:: Lifetime ) {
568584 if let Some ( syntax_category) = LifetimeSyntaxCategory :: new ( lifetime) {
569585 let info = Info { lifetime, syntax_category, ty : self . ty } ;
570- self . map . entry ( & lifetime . kind ) . or_default ( ) . push ( info) ;
586+ ( self . info_func ) ( info) ;
571587 }
572588 }
573589
0 commit comments