Skip to content

Commit 17ac62e

Browse files
committed
LifetimeSyntax tweak data structure
1 parent 86f8df3 commit 17ac62e

File tree

1 file changed

+45
-29
lines changed

1 file changed

+45
-29
lines changed

compiler/rustc_lint/src/lifetime_syntax.rs

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -111,35 +111,47 @@ impl<'tcx> LateLintPass<'tcx> for LifetimeSyntax {
111111
}
112112

113113
fn 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)]
144156
enum 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

Comments
 (0)