@@ -11,8 +11,6 @@ use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
1111use rustc_data_structures:: binary_search_util;
1212use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1313use rustc_data_structures:: graph:: scc:: Sccs ;
14- use rustc_data_structures:: graph:: vec_graph:: VecGraph ;
15- use rustc_data_structures:: graph:: WithSuccessors ;
1614use rustc_hir:: def_id:: DefId ;
1715use rustc_index:: bit_set:: BitSet ;
1816use rustc_index:: vec:: IndexVec ;
@@ -25,6 +23,7 @@ use crate::borrow_check::{
2523 diagnostics:: { RegionErrorKind , RegionErrors } ,
2624 member_constraints:: { MemberConstraintSet , NllMemberConstraintIndex } ,
2725 nll:: { PoloniusOutput , ToRegionVid } ,
26+ region_infer:: reverse_sccs:: ReverseSccGraph ,
2827 region_infer:: values:: {
2928 LivenessValues , PlaceholderIndices , RegionElement , RegionValueElements , RegionValues ,
3029 ToElementIndex ,
@@ -36,6 +35,7 @@ use crate::borrow_check::{
3635mod dump_mir;
3736mod graphviz;
3837mod opaque_types;
38+ mod reverse_sccs;
3939
4040pub mod values;
4141
@@ -65,9 +65,10 @@ pub struct RegionInferenceContext<'tcx> {
6565 /// compute the values of each region.
6666 pub ( in crate :: borrow_check) constraint_sccs : Rc < Sccs < RegionVid , ConstraintSccIndex > > ,
6767
68- /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
69- /// exists if `B: A`. Computed lazilly.
70- pub ( in crate :: borrow_check) rev_constraint_graph : Option < Rc < VecGraph < ConstraintSccIndex > > > ,
68+ /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
69+ /// `B: A`. This is used to compute the universal regions that are required
70+ /// to outlive a given SCC. Computed lazily.
71+ pub ( in crate :: borrow_check) rev_scc_graph : Option < Rc < ReverseSccGraph > > ,
7172
7273 /// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
7374 pub ( in crate :: borrow_check) member_constraints :
@@ -281,7 +282,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
281282 constraints,
282283 constraint_graph,
283284 constraint_sccs,
284- rev_constraint_graph : None ,
285+ rev_scc_graph : None ,
285286 member_constraints,
286287 member_constraints_applied : Vec :: new ( ) ,
287288 closure_bounds_mapping,
@@ -673,15 +674,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
673674 // free region that must outlive the member region `R0` (`UB:
674675 // R0`). Therefore, we need only keep an option `O` if `UB: O`
675676 // for all UB.
676- if choice_regions. len ( ) > 1 {
677- let universal_region_relations = self . universal_region_relations . clone ( ) ;
678- let rev_constraint_graph = self . rev_constraint_graph ( ) ;
679- for ub in self . upper_bounds ( scc, & rev_constraint_graph) {
680- debug ! ( "apply_member_constraint: ub={:?}" , ub) ;
681- choice_regions. retain ( |& o_r| universal_region_relations. outlives ( ub, o_r) ) ;
682- }
683- debug ! ( "apply_member_constraint: after ub, choice_regions={:?}" , choice_regions) ;
677+ let rev_scc_graph = self . reverse_scc_graph ( ) ;
678+ let universal_region_relations = & self . universal_region_relations ;
679+ for ub in rev_scc_graph. upper_bounds ( scc) {
680+ debug ! ( "apply_member_constraint: ub={:?}" , ub) ;
681+ choice_regions. retain ( |& o_r| universal_region_relations. outlives ( ub, o_r) ) ;
684682 }
683+ debug ! ( "apply_member_constraint: after ub, choice_regions={:?}" , choice_regions) ;
685684
686685 // If we ruled everything out, we're done.
687686 if choice_regions. is_empty ( ) {
@@ -737,32 +736,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
737736 }
738737 }
739738
740- /// Compute and return the reverse SCC-based constraint graph (lazilly).
741- fn upper_bounds (
742- & ' a mut self ,
743- scc0 : ConstraintSccIndex ,
744- rev_constraint_graph : & ' a VecGraph < ConstraintSccIndex > ,
745- ) -> impl Iterator < Item = RegionVid > + ' a {
746- let scc_values = & self . scc_values ;
747- let mut duplicates = FxHashSet :: default ( ) ;
748- rev_constraint_graph
749- . depth_first_search ( scc0)
750- . skip ( 1 )
751- . flat_map ( move |scc1| scc_values. universal_regions_outlived_by ( scc1) )
752- . filter ( move |& r| duplicates. insert ( r) )
753- }
754-
755- /// Compute and return the reverse SCC-based constraint graph (lazilly).
756- fn rev_constraint_graph ( & mut self ) -> Rc < VecGraph < ConstraintSccIndex > > {
757- if let Some ( g) = & self . rev_constraint_graph {
758- return g. clone ( ) ;
759- }
760-
761- let rev_graph = Rc :: new ( self . constraint_sccs . reverse ( ) ) ;
762- self . rev_constraint_graph = Some ( rev_graph. clone ( ) ) ;
763- rev_graph
764- }
765-
766739 /// Returns `true` if all the elements in the value of `scc_b` are nameable
767740 /// in `scc_a`. Used during constraint propagation, and only once
768741 /// the value of `scc_b` has been computed.
0 commit comments