@@ -12,8 +12,6 @@ use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
1212use rustc_data_structures:: binary_search_util;
1313use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1414use rustc_data_structures:: graph:: scc:: Sccs ;
15- use rustc_data_structures:: graph:: vec_graph:: VecGraph ;
16- use rustc_data_structures:: graph:: WithSuccessors ;
1715use rustc_hir:: def_id:: DefId ;
1816use rustc_index:: bit_set:: BitSet ;
1917use rustc_index:: vec:: IndexVec ;
@@ -26,6 +24,7 @@ use crate::borrow_check::{
2624 diagnostics:: { RegionErrorKind , RegionErrors } ,
2725 member_constraints:: { MemberConstraintSet , NllMemberConstraintIndex } ,
2826 nll:: { PoloniusOutput , ToRegionVid } ,
27+ region_infer:: reverse_sccs:: ReverseSccGraph ,
2928 region_infer:: values:: {
3029 LivenessValues , PlaceholderIndices , RegionElement , RegionValueElements , RegionValues ,
3130 ToElementIndex ,
@@ -37,6 +36,7 @@ use crate::borrow_check::{
3736mod dump_mir;
3837mod graphviz;
3938mod opaque_types;
39+ mod reverse_sccs;
4040
4141pub mod values;
4242
@@ -66,9 +66,10 @@ pub struct RegionInferenceContext<'tcx> {
6666 /// compute the values of each region.
6767 constraint_sccs : Rc < Sccs < RegionVid , ConstraintSccIndex > > ,
6868
69- /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
70- /// exists if `B: A`. Computed lazilly.
71- rev_constraint_graph : Option < Rc < VecGraph < ConstraintSccIndex > > > ,
69+ /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
70+ /// `B: A`. This is used to compute the universal regions that are required
71+ /// to outlive a given SCC. Computed lazily.
72+ rev_scc_graph : Option < Rc < ReverseSccGraph > > ,
7273
7374 /// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
7475 member_constraints : Rc < MemberConstraintSet < ' tcx , ConstraintSccIndex > > ,
@@ -288,7 +289,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
288289 constraints,
289290 constraint_graph,
290291 constraint_sccs,
291- rev_constraint_graph : None ,
292+ rev_scc_graph : None ,
292293 member_constraints,
293294 member_constraints_applied : Vec :: new ( ) ,
294295 closure_bounds_mapping,
@@ -680,15 +681,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
680681 // free region that must outlive the member region `R0` (`UB:
681682 // R0`). Therefore, we need only keep an option `O` if `UB: O`
682683 // for all UB.
683- if choice_regions. len ( ) > 1 {
684- let universal_region_relations = self . universal_region_relations . clone ( ) ;
685- let rev_constraint_graph = self . rev_constraint_graph ( ) ;
686- for ub in self . upper_bounds ( scc, & rev_constraint_graph) {
687- debug ! ( "apply_member_constraint: ub={:?}" , ub) ;
688- choice_regions. retain ( |& o_r| universal_region_relations. outlives ( ub, o_r) ) ;
689- }
690- debug ! ( "apply_member_constraint: after ub, choice_regions={:?}" , choice_regions) ;
684+ let rev_scc_graph = self . reverse_scc_graph ( ) ;
685+ let universal_region_relations = & self . universal_region_relations ;
686+ for ub in rev_scc_graph. upper_bounds ( scc) {
687+ debug ! ( "apply_member_constraint: ub={:?}" , ub) ;
688+ choice_regions. retain ( |& o_r| universal_region_relations. outlives ( ub, o_r) ) ;
691689 }
690+ debug ! ( "apply_member_constraint: after ub, choice_regions={:?}" , choice_regions) ;
692691
693692 // If we ruled everything out, we're done.
694693 if choice_regions. is_empty ( ) {
@@ -744,32 +743,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
744743 }
745744 }
746745
747- /// Compute and return the reverse SCC-based constraint graph (lazilly).
748- fn upper_bounds (
749- & ' a mut self ,
750- scc0 : ConstraintSccIndex ,
751- rev_constraint_graph : & ' a VecGraph < ConstraintSccIndex > ,
752- ) -> impl Iterator < Item = RegionVid > + ' a {
753- let scc_values = & self . scc_values ;
754- let mut duplicates = FxHashSet :: default ( ) ;
755- rev_constraint_graph
756- . depth_first_search ( scc0)
757- . skip ( 1 )
758- . flat_map ( move |scc1| scc_values. universal_regions_outlived_by ( scc1) )
759- . filter ( move |& r| duplicates. insert ( r) )
760- }
761-
762- /// Compute and return the reverse SCC-based constraint graph (lazilly).
763- fn rev_constraint_graph ( & mut self ) -> Rc < VecGraph < ConstraintSccIndex > > {
764- if let Some ( g) = & self . rev_constraint_graph {
765- return g. clone ( ) ;
766- }
767-
768- let rev_graph = Rc :: new ( self . constraint_sccs . reverse ( ) ) ;
769- self . rev_constraint_graph = Some ( rev_graph. clone ( ) ) ;
770- rev_graph
771- }
772-
773746 /// Returns `true` if all the elements in the value of `scc_b` are nameable
774747 /// in `scc_a`. Used during constraint propagation, and only once
775748 /// the value of `scc_b` has been computed.
0 commit comments