11use rustc_data_structures:: fx:: FxIndexSet ;
22use rustc_data_structures:: transitive_relation:: TransitiveRelationBuilder ;
3- use rustc_middle:: bug;
4- use rustc_middle:: ty:: { self , Region } ;
5- use tracing:: { debug, instrument} ;
3+ use rustc_middle:: { bug, ty} ;
4+ use tracing:: debug;
65
76use super :: explicit_outlives_bounds;
87use crate :: infer:: GenericKind ;
@@ -54,94 +53,44 @@ pub struct OutlivesEnvironment<'tcx> {
5453region_bound_pairs : RegionBoundPairs < ' tcx > ,
5554}
5655
57- /// Builder of OutlivesEnvironment.
58- #[ derive( Debug ) ]
59- struct OutlivesEnvironmentBuilder < ' tcx > {
60- param_env : ty:: ParamEnv < ' tcx > ,
61- region_relation : TransitiveRelationBuilder < Region < ' tcx > > ,
62- region_bound_pairs : RegionBoundPairs < ' tcx > ,
63- }
64-
6556/// "Region-bound pairs" tracks outlives relations that are known to
6657/// be true, either because of explicit where-clauses like `T: 'a` or
6758/// because of implied bounds.
6859pub type RegionBoundPairs < ' tcx > = FxIndexSet < ty:: OutlivesPredicate < ' tcx , GenericKind < ' tcx > > > ;
6960
7061impl < ' tcx > OutlivesEnvironment < ' tcx > {
71- /// Create a builder using `ParamEnv` and add explicit outlives bounds into it.
72- fn builder ( param_env : ty:: ParamEnv < ' tcx > ) -> OutlivesEnvironmentBuilder < ' tcx > {
73- let mut builder = OutlivesEnvironmentBuilder {
74- param_env,
75- region_relation : Default :: default ( ) ,
76- region_bound_pairs : Default :: default ( ) ,
77- } ;
78-
79- builder. add_outlives_bounds ( explicit_outlives_bounds ( param_env) ) ;
80-
81- builder
82- }
83-
84- #[ inline]
8562/// Create a new `OutlivesEnvironment` without extra outlives bounds.
63+ #[ inline]
8664pub fn new ( param_env : ty:: ParamEnv < ' tcx > ) -> Self {
87- Self :: builder ( param_env) . build ( )
65+ Self :: with_bounds ( param_env, vec ! [ ] )
8866}
8967
9068/// Create a new `OutlivesEnvironment` with extra outlives bounds.
9169pub fn with_bounds (
9270param_env : ty:: ParamEnv < ' tcx > ,
9371extra_bounds : impl IntoIterator < Item = OutlivesBound < ' tcx > > ,
9472) -> Self {
95- let mut builder = Self :: builder ( param_env) ;
96- builder. add_outlives_bounds ( extra_bounds) ;
97- builder. build ( )
98- }
73+ let mut region_relation = TransitiveRelationBuilder :: default ( ) ;
74+ let mut region_bound_pairs = RegionBoundPairs :: default ( ) ;
9975
100- /// Borrows current value of the `free_region_map`.
101- pub fn free_region_map ( & self ) -> & FreeRegionMap < ' tcx > {
102- & self . free_region_map
103- }
104-
105- /// Borrows current `region_bound_pairs`.
106- pub fn region_bound_pairs ( & self ) -> & RegionBoundPairs < ' tcx > {
107- & self . region_bound_pairs
108- }
109- }
110-
111- impl < ' tcx > OutlivesEnvironmentBuilder < ' tcx > {
112- #[ inline]
113- #[ instrument( level = "debug" ) ]
114- fn build ( self ) -> OutlivesEnvironment < ' tcx > {
115- OutlivesEnvironment {
116- param_env : self . param_env ,
117- free_region_map : FreeRegionMap { relation : self . region_relation . freeze ( ) } ,
118- region_bound_pairs : self . region_bound_pairs ,
119- }
120- }
121-
122- /// Processes outlives bounds that are known to hold, whether from implied or other sources.
123- fn add_outlives_bounds < I > ( & mut self , outlives_bounds : I )
124- where
125- I : IntoIterator < Item = OutlivesBound < ' tcx > > ,
126- {
12776// Record relationships such as `T:'x` that don't go into the
12877// free-region-map but which we use here.
129- for outlives_bound in outlives_bounds {
78+ for outlives_bound in explicit_outlives_bounds ( param_env ) . chain ( extra_bounds ) {
13079debug ! ( "add_outlives_bounds: outlives_bound={:?}" , outlives_bound) ;
13180match outlives_bound {
13281OutlivesBound :: RegionSubParam ( r_a, param_b) => {
133- self . region_bound_pairs
82+ region_bound_pairs
13483. insert ( ty:: OutlivesPredicate ( GenericKind :: Param ( param_b) , r_a) ) ;
13584}
13685OutlivesBound :: RegionSubAlias ( r_a, alias_b) => {
137- self . region_bound_pairs
86+ region_bound_pairs
13887. insert ( ty:: OutlivesPredicate ( GenericKind :: Alias ( alias_b) , r_a) ) ;
13988}
14089OutlivesBound :: RegionSubRegion ( r_a, r_b) => match ( * r_a, * r_b) {
14190(
14291 ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
14392 ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
144- ) => self . region_relation . add ( r_a, r_b) ,
93+ ) => region_relation. add ( r_a, r_b) ,
14594( ty:: ReError ( _) , _) | ( _, ty:: ReError ( _) ) => { }
14695// FIXME(#109628): We shouldn't have existential variables in implied bounds.
14796// Panic here once the linked issue is resolved!
@@ -150,5 +99,21 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
15099} ,
151100}
152101}
102+
103+ OutlivesEnvironment {
104+ param_env,
105+ free_region_map : FreeRegionMap { relation : region_relation. freeze ( ) } ,
106+ region_bound_pairs,
107+ }
108+ }
109+
110+ /// Borrows current value of the `free_region_map`.
111+ pub fn free_region_map ( & self ) -> & FreeRegionMap < ' tcx > {
112+ & self . free_region_map
113+ }
114+
115+ /// Borrows current `region_bound_pairs`.
116+ pub fn region_bound_pairs ( & self ) -> & RegionBoundPairs < ' tcx > {
117+ & self . region_bound_pairs
153118}
154119}
0 commit comments