1313use middle:: implicator:: Implication ;
1414use middle:: ty:: { self , FreeRegion } ;
1515use util:: common:: can_reach;
16- use util:: nodemap:: FnvHashMap ;
16+ use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
1717
1818#[ derive( Clone ) ]
1919pub struct FreeRegionMap {
20- /// `free_region_map ` maps from a free region `a` to a list of
20+ /// `map ` maps from a free region `a` to a list of
2121 /// free regions `bs` such that `a <= b for all b in bs`
2222 map : FnvHashMap < FreeRegion , Vec < FreeRegion > > ,
23+ /// regions that are required to outlive (and therefore be
24+ /// equal to) 'static.
25+ statics : FnvHashSet < FreeRegion >
2326}
2427
2528impl FreeRegionMap {
2629 pub fn new ( ) -> FreeRegionMap {
27- FreeRegionMap { map : FnvHashMap ( ) }
30+ FreeRegionMap { map : FnvHashMap ( ) , statics : FnvHashSet ( ) }
2831 }
2932
3033 pub fn relate_free_regions_from_implications < ' tcx > ( & mut self ,
@@ -59,6 +62,8 @@ impl FreeRegionMap {
5962 }
6063 ty:: Predicate :: RegionOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( r_a, r_b) ) ) => {
6164 match ( r_a, r_b) {
65+ ( ty:: ReStatic , ty:: ReFree ( _) ) => { } ,
66+ ( ty:: ReFree ( fr_a) , ty:: ReStatic ) => self . relate_to_static ( fr_a) ,
6267 ( ty:: ReFree ( fr_a) , ty:: ReFree ( fr_b) ) => {
6368 // Record that `'a:'b`. Or, put another way, `'b <= 'a`.
6469 self . relate_free_regions ( fr_b, fr_a) ;
@@ -76,8 +81,12 @@ impl FreeRegionMap {
7681 }
7782 }
7883
79- pub fn relate_free_regions ( & mut self , sub : FreeRegion , sup : FreeRegion ) {
80- let mut sups = self . map . entry ( sub) . or_insert ( Vec :: new ( ) ) ;
84+ fn relate_to_static ( & mut self , sup : FreeRegion ) {
85+ self . statics . insert ( sup) ;
86+ }
87+
88+ fn relate_free_regions ( & mut self , sub : FreeRegion , sup : FreeRegion ) {
89+ let mut sups = self . map . entry ( sub) . or_insert ( Vec :: new ( ) ) ;
8190 if !sups. contains ( & sup) {
8291 sups. push ( sup) ;
8392 }
@@ -88,7 +97,7 @@ impl FreeRegionMap {
8897 /// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
8998 /// (that is, the user can give two different names to the same lifetime).
9099 pub fn sub_free_region ( & self , sub : FreeRegion , sup : FreeRegion ) -> bool {
91- can_reach ( & self . map , sub, sup)
100+ can_reach ( & self . map , sub, sup) || self . is_static ( & sup )
92101 }
93102
94103 /// Determines whether one region is a subregion of another. This is intended to run *after
@@ -116,10 +125,17 @@ impl FreeRegionMap {
116125 ( ty:: ReFree ( sub_fr) , ty:: ReFree ( super_fr) ) =>
117126 self . sub_free_region ( sub_fr, super_fr) ,
118127
128+ ( ty:: ReStatic , ty:: ReFree ( ref sup_fr) ) => self . is_static ( sup_fr) ,
129+
119130 _ =>
120131 false ,
121132 }
122133 }
123134 }
124- }
125135
136+ /// Determines whether this free-region is required to be 'static
137+ pub fn is_static ( & self , super_region : & ty:: FreeRegion ) -> bool {
138+ debug ! ( "is_static(super_region={:?})" , super_region) ;
139+ self . statics . iter ( ) . any ( |s| can_reach ( & self . map , * s, * super_region) )
140+ }
141+ }
0 commit comments