1
Fork 0

Remove unnecessary lifetime from LeakCheck.

`LeakCheck` can own `mini_graph` and `rcc` instead of holding references
to them. This requires inlining `assign_scc_value` to avoid a borrowck
error, but that's fine because it has a single call site.
This commit is contained in:
Nicholas Nethercote 2024-10-03 13:58:13 +10:00
parent 85507cffc3
commit e8a0bd6549

View file

@ -73,7 +73,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
/// * R: P1, R: P2, as above /// * R: P1, R: P2, as above
#[instrument(level = "debug", skip(self, tcx, only_consider_snapshot), ret)] #[instrument(level = "debug", skip(self, tcx, only_consider_snapshot), ret)]
pub fn leak_check( pub fn leak_check(
&mut self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
outer_universe: ty::UniverseIndex, outer_universe: ty::UniverseIndex,
max_universe: ty::UniverseIndex, max_universe: ty::UniverseIndex,
@ -83,7 +83,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
return Ok(()); return Ok(());
} }
let mini_graph = &MiniGraph::new(tcx, self, only_consider_snapshot); let mini_graph = MiniGraph::new(tcx, &self, only_consider_snapshot);
let mut leak_check = LeakCheck::new(tcx, outer_universe, max_universe, mini_graph, self); let mut leak_check = LeakCheck::new(tcx, outer_universe, max_universe, mini_graph, self);
leak_check.assign_placeholder_values()?; leak_check.assign_placeholder_values()?;
@ -92,11 +92,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
} }
} }
struct LeakCheck<'a, 'b, 'tcx> { struct LeakCheck<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
outer_universe: ty::UniverseIndex, outer_universe: ty::UniverseIndex,
mini_graph: &'a MiniGraph<'tcx>, mini_graph: MiniGraph<'tcx>,
rcc: &'a mut RegionConstraintCollector<'b, 'tcx>, rcc: RegionConstraintCollector<'a, 'tcx>,
// Initially, for each SCC S, stores a placeholder `P` such that `S = P` // Initially, for each SCC S, stores a placeholder `P` such that `S = P`
// must hold. // must hold.
@ -115,26 +115,27 @@ struct LeakCheck<'a, 'b, 'tcx> {
// either the placeholder `P1` or the empty region in that same universe. // either the placeholder `P1` or the empty region in that same universe.
// //
// To detect errors, we look for an SCC S where the values in // To detect errors, we look for an SCC S where the values in
// `scc_values[S]` (if any) cannot be stored into `scc_universes[S]`. // `scc_placeholders[S]` (if any) cannot be stored into `scc_universes[S]`.
scc_universes: IndexVec<LeakCheckScc, SccUniverse<'tcx>>, scc_universes: IndexVec<LeakCheckScc, SccUniverse<'tcx>>,
} }
impl<'a, 'b, 'tcx> LeakCheck<'a, 'b, 'tcx> { impl<'a, 'tcx> LeakCheck<'a, 'tcx> {
fn new( fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
outer_universe: ty::UniverseIndex, outer_universe: ty::UniverseIndex,
max_universe: ty::UniverseIndex, max_universe: ty::UniverseIndex,
mini_graph: &'a MiniGraph<'tcx>, mini_graph: MiniGraph<'tcx>,
rcc: &'a mut RegionConstraintCollector<'b, 'tcx>, rcc: RegionConstraintCollector<'a, 'tcx>,
) -> Self { ) -> Self {
let dummy_scc_universe = SccUniverse { universe: max_universe, region: None }; let dummy_scc_universe = SccUniverse { universe: max_universe, region: None };
let num_sccs = mini_graph.sccs.num_sccs();
Self { Self {
tcx, tcx,
outer_universe, outer_universe,
mini_graph, mini_graph,
rcc, rcc,
scc_placeholders: IndexVec::from_elem_n(None, mini_graph.sccs.num_sccs()), scc_placeholders: IndexVec::from_elem_n(None, num_sccs),
scc_universes: IndexVec::from_elem_n(dummy_scc_universe, mini_graph.sccs.num_sccs()), scc_universes: IndexVec::from_elem_n(dummy_scc_universe, num_sccs),
} }
} }
@ -156,7 +157,16 @@ impl<'a, 'b, 'tcx> LeakCheck<'a, 'b, 'tcx> {
// Detect those SCCs that directly contain a placeholder // Detect those SCCs that directly contain a placeholder
if let ty::RePlaceholder(placeholder) = **region { if let ty::RePlaceholder(placeholder) = **region {
if self.outer_universe.cannot_name(placeholder.universe) { if self.outer_universe.cannot_name(placeholder.universe) {
self.assign_scc_value(scc, placeholder)?; // Update `scc_placeholders` to account for the fact that `P: S` must hold.
match self.scc_placeholders[scc] {
Some(p) => {
assert_ne!(p, placeholder);
return Err(self.placeholder_error(p, placeholder));
}
None => {
self.scc_placeholders[scc] = Some(placeholder);
}
}
} }
} }
} }
@ -164,26 +174,6 @@ impl<'a, 'b, 'tcx> LeakCheck<'a, 'b, 'tcx> {
Ok(()) Ok(())
} }
// assign_scc_value(S, P): Update `scc_values` to account for the fact that `P: S` must hold.
// This may create an error.
fn assign_scc_value(
&mut self,
scc: LeakCheckScc,
placeholder: ty::PlaceholderRegion,
) -> RelateResult<'tcx, ()> {
match self.scc_placeholders[scc] {
Some(p) => {
assert_ne!(p, placeholder);
return Err(self.placeholder_error(p, placeholder));
}
None => {
self.scc_placeholders[scc] = Some(placeholder);
}
};
Ok(())
}
/// For each SCC S, iterate over each successor S1 where `S: S1`: /// For each SCC S, iterate over each successor S1 where `S: S1`:
/// ///
/// * Compute /// * Compute