1
1
use rustc_data_structures:: fx:: FxIndexSet ;
2
2
use rustc_data_structures:: transitive_relation:: TransitiveRelationBuilder ;
3
3
use rustc_middle:: { bug, ty} ;
4
- use tracing:: debug;
5
4
6
- use super :: explicit_outlives_bounds;
7
5
use crate :: infer:: GenericKind ;
8
6
use crate :: infer:: free_regions:: FreeRegionMap ;
9
- use crate :: traits:: query:: OutlivesBound ;
10
7
11
8
/// The `OutlivesEnvironment` collects information about what outlives
12
9
/// what in a given type-checking setting. For example, if we have a
@@ -31,26 +28,7 @@ use crate::traits::query::OutlivesBound;
31
28
pub struct OutlivesEnvironment < ' tcx > {
32
29
pub param_env : ty:: ParamEnv < ' tcx > ,
33
30
free_region_map : FreeRegionMap < ' tcx > ,
34
-
35
- // Contains the implied region bounds in scope for our current body.
36
- //
37
- // Example:
38
- //
39
- // ```
40
- // fn foo<'a, 'b, T>(x: &'a T, y: &'b ()) {
41
- // bar(x, y, |y: &'b T| { .. } // body B1)
42
- // } // body B0
43
- // ```
44
- //
45
- // Here, when checking the body B0, the list would be `[T: 'a]`, because we
46
- // infer that `T` must outlive `'a` from the implied bounds on the
47
- // fn declaration.
48
- //
49
- // For the body B1 however, the list would be `[T: 'a, T: 'b]`, because we
50
- // also can see that -- within the closure body! -- `T` must
51
- // outlive `'b`. This is not necessarily true outside the closure
52
- // body, since the closure may never be called.
53
- region_bound_pairs : RegionBoundPairs < ' tcx > ,
31
+ known_type_outlives : Vec < ty:: PolyTypeOutlivesPredicate < ' tcx > > ,
54
32
}
55
33
56
34
/// "Region-bound pairs" tracks outlives relations that are known to
@@ -59,45 +37,54 @@ pub struct OutlivesEnvironment<'tcx> {
59
37
pub type RegionBoundPairs < ' tcx > = FxIndexSet < ty:: OutlivesPredicate < ' tcx , GenericKind < ' tcx > > > ;
60
38
61
39
impl < ' tcx > OutlivesEnvironment < ' tcx > {
62
- /// Create a new `OutlivesEnvironment` with extra outlives bounds.
63
- pub fn with_bounds (
40
+ /// Create a new `OutlivesEnvironment` from normalized outlives bounds.
41
+ pub fn from_normalized_bounds (
64
42
param_env : ty:: ParamEnv < ' tcx > ,
65
- extra_bounds : impl IntoIterator < Item = OutlivesBound < ' tcx > > ,
43
+ bounds : impl IntoIterator <
44
+ Item = ty:: Binder < ' tcx , ty:: OutlivesPredicate < ' tcx , ty:: GenericArg < ' tcx > > > ,
45
+ > ,
66
46
) -> Self {
47
+ let mut known_type_outlives = vec ! [ ] ;
67
48
let mut region_relation = TransitiveRelationBuilder :: default ( ) ;
68
- let mut region_bound_pairs = RegionBoundPairs :: default ( ) ;
69
49
70
50
// Record relationships such as `T:'x` that don't go into the
71
51
// free-region-map but which we use here.
72
- for outlives_bound in explicit_outlives_bounds ( param_env) . chain ( extra_bounds) {
73
- debug ! ( "add_outlives_bounds: outlives_bound={:?}" , outlives_bound) ;
74
- match outlives_bound {
75
- OutlivesBound :: RegionSubParam ( r_a, param_b) => {
76
- region_bound_pairs
77
- . insert ( ty:: OutlivesPredicate ( GenericKind :: Param ( param_b) , r_a) ) ;
52
+ for bound in bounds {
53
+ let ty:: OutlivesPredicate ( arg_b, r_a) = bound. skip_binder ( ) ;
54
+ match arg_b. unpack ( ) {
55
+ ty:: GenericArgKind :: Lifetime ( r_b) => {
56
+ match ( * r_a, * r_b) {
57
+ (
58
+ ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
59
+ ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
60
+ ) => region_relation. add ( r_a, r_b) ,
61
+ // Do nothing for higher-ranked region predicates.
62
+ (
63
+ ty:: ReBound ( ..) ,
64
+ ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
65
+ )
66
+ | (
67
+ ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
68
+ ty:: ReBound ( ..) ,
69
+ ) => { }
70
+ ( ty:: ReError ( _) , _) | ( _, ty:: ReError ( _) ) => { }
71
+ // FIXME(#109628): We shouldn't have existential variables in implied bounds.
72
+ // Panic here once the linked issue is resolved!
73
+ ( ty:: ReVar ( _) , _) | ( _, ty:: ReVar ( _) ) => { }
74
+ _ => bug ! ( "add_outlives_bounds: unexpected regions: ({r_a:?}, {r_b:?})" ) ,
75
+ }
78
76
}
79
- OutlivesBound :: RegionSubAlias ( r_a, alias_b) => {
80
- region_bound_pairs
81
- . insert ( ty:: OutlivesPredicate ( GenericKind :: Alias ( alias_b) , r_a) ) ;
77
+ ty:: GenericArgKind :: Type ( ty_b) => {
78
+ known_type_outlives. push ( bound. rebind ( ty:: OutlivesPredicate ( ty_b, r_a) ) ) ;
82
79
}
83
- OutlivesBound :: RegionSubRegion ( r_a, r_b) => match ( * r_a, * r_b) {
84
- (
85
- ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
86
- ty:: ReStatic | ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) ,
87
- ) => region_relation. add ( r_a, r_b) ,
88
- ( ty:: ReError ( _) , _) | ( _, ty:: ReError ( _) ) => { }
89
- // FIXME(#109628): We shouldn't have existential variables in implied bounds.
90
- // Panic here once the linked issue is resolved!
91
- ( ty:: ReVar ( _) , _) | ( _, ty:: ReVar ( _) ) => { }
92
- _ => bug ! ( "add_outlives_bounds: unexpected regions: ({r_a:?}, {r_b:?})" ) ,
93
- } ,
80
+ ty:: GenericArgKind :: Const ( _) => unreachable ! ( ) ,
94
81
}
95
82
}
96
83
97
84
OutlivesEnvironment {
98
85
param_env,
86
+ known_type_outlives,
99
87
free_region_map : FreeRegionMap { relation : region_relation. freeze ( ) } ,
100
- region_bound_pairs,
101
88
}
102
89
}
103
90
@@ -107,7 +94,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
107
94
}
108
95
109
96
/// Borrows current `region_bound_pairs`.
110
- pub fn region_bound_pairs ( & self ) -> & RegionBoundPairs < ' tcx > {
111
- & self . region_bound_pairs
97
+ pub fn known_type_outlives ( & self ) -> & [ ty :: PolyTypeOutlivesPredicate < ' tcx > ] {
98
+ & self . known_type_outlives
112
99
}
113
100
}
0 commit comments