13
13
use middle:: implicator:: Implication ;
14
14
use middle:: ty:: { self , FreeRegion } ;
15
15
use util:: common:: can_reach;
16
- use util:: nodemap:: FnvHashMap ;
16
+ use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
17
17
18
18
#[ derive( Clone ) ]
19
19
pub 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
21
21
/// free regions `bs` such that `a <= b for all b in bs`
22
22
map : FnvHashMap < FreeRegion , Vec < FreeRegion > > ,
23
+ /// regions that are required to outlive (and therefore be
24
+ /// equal to) 'static.
25
+ statics : FnvHashSet < FreeRegion >
23
26
}
24
27
25
28
impl FreeRegionMap {
26
29
pub fn new ( ) -> FreeRegionMap {
27
- FreeRegionMap { map : FnvHashMap ( ) }
30
+ FreeRegionMap { map : FnvHashMap ( ) , statics : FnvHashSet ( ) }
28
31
}
29
32
30
33
pub fn relate_free_regions_from_implications < ' tcx > ( & mut self ,
@@ -59,6 +62,8 @@ impl FreeRegionMap {
59
62
}
60
63
ty:: Predicate :: RegionOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( r_a, r_b) ) ) => {
61
64
match ( r_a, r_b) {
65
+ ( ty:: ReStatic , ty:: ReFree ( _) ) => { } ,
66
+ ( ty:: ReFree ( fr_a) , ty:: ReStatic ) => self . relate_to_static ( fr_a) ,
62
67
( ty:: ReFree ( fr_a) , ty:: ReFree ( fr_b) ) => {
63
68
// Record that `'a:'b`. Or, put another way, `'b <= 'a`.
64
69
self . relate_free_regions ( fr_b, fr_a) ;
@@ -76,8 +81,12 @@ impl FreeRegionMap {
76
81
}
77
82
}
78
83
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 ( ) ) ;
81
90
if !sups. contains ( & sup) {
82
91
sups. push ( sup) ;
83
92
}
@@ -88,7 +97,7 @@ impl FreeRegionMap {
88
97
/// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
89
98
/// (that is, the user can give two different names to the same lifetime).
90
99
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 )
92
101
}
93
102
94
103
/// Determines whether one region is a subregion of another. This is intended to run *after
@@ -116,10 +125,17 @@ impl FreeRegionMap {
116
125
( ty:: ReFree ( sub_fr) , ty:: ReFree ( super_fr) ) =>
117
126
self . sub_free_region ( sub_fr, super_fr) ,
118
127
128
+ ( ty:: ReStatic , ty:: ReFree ( ref sup_fr) ) => self . is_static ( sup_fr) ,
129
+
119
130
_ =>
120
131
false ,
121
132
}
122
133
}
123
134
}
124
- }
125
135
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