@@ -11,8 +11,6 @@ use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
11
11
use rustc_data_structures:: binary_search_util;
12
12
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
13
13
use rustc_data_structures:: graph:: scc:: Sccs ;
14
- use rustc_data_structures:: graph:: vec_graph:: VecGraph ;
15
- use rustc_data_structures:: graph:: WithSuccessors ;
16
14
use rustc_hir:: def_id:: DefId ;
17
15
use rustc_index:: bit_set:: BitSet ;
18
16
use rustc_index:: vec:: IndexVec ;
@@ -25,6 +23,7 @@ use crate::borrow_check::{
25
23
diagnostics:: { RegionErrorKind , RegionErrors } ,
26
24
member_constraints:: { MemberConstraintSet , NllMemberConstraintIndex } ,
27
25
nll:: { PoloniusOutput , ToRegionVid } ,
26
+ region_infer:: reverse_sccs:: ReverseSccGraph ,
28
27
region_infer:: values:: {
29
28
LivenessValues , PlaceholderIndices , RegionElement , RegionValueElements , RegionValues ,
30
29
ToElementIndex ,
@@ -36,6 +35,7 @@ use crate::borrow_check::{
36
35
mod dump_mir;
37
36
mod graphviz;
38
37
mod opaque_types;
38
+ mod reverse_sccs;
39
39
40
40
pub mod values;
41
41
@@ -65,9 +65,10 @@ pub struct RegionInferenceContext<'tcx> {
65
65
/// compute the values of each region.
66
66
pub ( in crate :: borrow_check) constraint_sccs : Rc < Sccs < RegionVid , ConstraintSccIndex > > ,
67
67
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 > > ,
71
72
72
73
/// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
73
74
pub ( in crate :: borrow_check) member_constraints :
@@ -281,7 +282,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
281
282
constraints,
282
283
constraint_graph,
283
284
constraint_sccs,
284
- rev_constraint_graph : None ,
285
+ rev_scc_graph : None ,
285
286
member_constraints,
286
287
member_constraints_applied : Vec :: new ( ) ,
287
288
closure_bounds_mapping,
@@ -673,15 +674,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
673
674
// free region that must outlive the member region `R0` (`UB:
674
675
// R0`). Therefore, we need only keep an option `O` if `UB: O`
675
676
// 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) ) ;
684
682
}
683
+ debug ! ( "apply_member_constraint: after ub, choice_regions={:?}" , choice_regions) ;
685
684
686
685
// If we ruled everything out, we're done.
687
686
if choice_regions. is_empty ( ) {
@@ -737,32 +736,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
737
736
}
738
737
}
739
738
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
-
766
739
/// Returns `true` if all the elements in the value of `scc_b` are nameable
767
740
/// in `scc_a`. Used during constraint propagation, and only once
768
741
/// the value of `scc_b` has been computed.
0 commit comments