diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs index 7ecf3e3cb8d5dbfc23b8cac2e62fdf091775d863..57eaf56f268f86505a86f67ecb7ec0c4cd73d132 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/src/librustc_data_structures/graph/scc/mod.rs @@ -47,6 +47,11 @@ pub fn num_sccs(&self) -> usize { } /// Returns an iterator over the SCCs in the graph. + /// + /// The SCCs will be iterated in **dependency order** (or **post order**), + /// meaning that if `S1 -> S2`, we will visit `S2` first and `S1` after. + /// This is convenient when the edges represent dependencies: when you visit + /// `S1`, the value for `S2` will already have been computed. pub fn all_sccs(&self) -> impl Iterator { (0..self.scc_data.len()).map(S::new) } diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 880edf706a5d4bae01c712ffde10dc773653b38c..09eb1bb2fc482eca729a5e4a115318db2f77c4a5 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -6,7 +6,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_hir::def_id::DefId; -use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::canonical::QueryOutlivesConstraint; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound}; @@ -67,12 +66,6 @@ pub struct RegionInferenceContext<'tcx> { /// compute the values of each region. constraint_sccs: Rc>, - /// SCCs in "dependency order" (or "post order"), meaning that if S1 -> S2, - /// then S2 appears first. If you process the SCCs in this order, then you - /// are always ensured that when you proces a given SCC, all of its - /// successors have been processed. - scc_dependency_order: Vec, - /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required /// to outlive a given SCC. Computed lazily. @@ -283,10 +276,7 @@ pub(in crate::borrow_check) fn new( scc_values.merge_liveness(scc, region, &liveness_constraints); } - let scc_dependency_order = Self::compute_scc_dependency_order(&constraint_sccs); - - let scc_universes = - Self::compute_scc_universes(&constraint_sccs, &scc_dependency_order, &definitions); + let scc_universes = Self::compute_scc_universes(&constraint_sccs, &definitions); let scc_representatives = Self::compute_scc_representatives(&constraint_sccs, &definitions); @@ -299,7 +289,6 @@ pub(in crate::borrow_check) fn new( constraints, constraint_graph, constraint_sccs, - scc_dependency_order, rev_scc_graph: None, member_constraints, member_constraints_applied: Vec::new(), @@ -317,43 +306,6 @@ pub(in crate::borrow_check) fn new( result } - /// Returns a vector of all scc-ids in "dependency" or "post order". See the - /// `scc_dependency_order` field for more details. - fn compute_scc_dependency_order( - constraints_scc: &Sccs, - ) -> Vec { - let mut visited = &mut BitSet::new_empty(constraints_scc.num_sccs()); - let mut output = vec![]; - - for scc in constraints_scc.all_sccs() { - Self::compute_scc_dependency_order_if_new( - constraints_scc, - scc, - &mut visited, - &mut output, - ); - } - - output - } - - fn compute_scc_dependency_order_if_new( - constraints_scc: &Sccs, - index: ConstraintSccIndex, - visited: &mut BitSet, - output: &mut Vec, - ) { - if !visited.insert(index) { - return; - } - - for &succ in constraints_scc.successors(index) { - Self::compute_scc_dependency_order_if_new(constraints_scc, succ, visited, output); - } - - output.push(index); - } - /// Each SCC is the combination of many region variables which /// have been equated. Therefore, we can associate a universe with /// each SCC which is minimum of all the universes of its @@ -363,7 +315,6 @@ fn compute_scc_dependency_order_if_new( /// the minimum, or narrowest, universe. fn compute_scc_universes( constraint_sccs: &Sccs, - scc_dependency_order: &[ConstraintSccIndex], definitions: &IndexVec>, ) -> IndexVec { let num_sccs = constraint_sccs.num_sccs(); @@ -420,7 +371,7 @@ fn compute_scc_universes( // constraint lowers the universe of `R1` to `U0`, which in turn // means that the `R1: !1` constraint will (later) cause // `R1` to become `'static`. - for &scc_a in scc_dependency_order { + for scc_a in constraint_sccs.all_sccs() { for &scc_b in constraint_sccs.successors(scc_a) { let scc_universe_a = scc_universes[scc_a]; let scc_universe_b = scc_universes[scc_b]; @@ -664,8 +615,9 @@ fn propagate_constraints(&mut self, _body: &Body<'tcx>) { // SCC. For each SCC, we visit its successors and compute // their values, then we union all those values to get our // own. - for i in 0..self.scc_dependency_order.len() { - self.compute_value_for_scc(self.scc_dependency_order[i]); + let constraint_sccs = self.constraint_sccs.clone(); + for scc in constraint_sccs.all_sccs() { + self.compute_value_for_scc(scc); } // Sort the applied member constraints so we can binary search