@@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap;
2
2
use rustc_hir:: def:: DefKind ;
3
3
use rustc_hir:: def_id:: DefId ;
4
4
use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , Subst } ;
5
- use rustc_middle:: ty:: { self , EarlyBinder , Ty , TyCtxt } ;
5
+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
6
6
use rustc_span:: Span ;
7
7
8
8
use super :: explicit:: ExplicitPredicatesMap ;
@@ -13,20 +13,19 @@ use super::utils::*;
13
13
/// `global_inferred_outlives`: this is initially the empty map that
14
14
/// was generated by walking the items in the crate. This will
15
15
/// now be filled with inferred predicates.
16
- pub fn infer_predicates < ' tcx > (
16
+ pub ( super ) fn infer_predicates < ' tcx > (
17
17
tcx : TyCtxt < ' tcx > ,
18
- explicit_map : & mut ExplicitPredicatesMap < ' tcx > ,
19
- ) -> FxHashMap < DefId , RequiredPredicates < ' tcx > > {
18
+ ) -> FxHashMap < DefId , ty:: EarlyBinder < RequiredPredicates < ' tcx > > > {
20
19
debug ! ( "infer_predicates" ) ;
21
20
22
- let mut predicates_added = true ;
21
+ let mut explicit_map = ExplicitPredicatesMap :: new ( ) ;
23
22
24
23
let mut global_inferred_outlives = FxHashMap :: default ( ) ;
25
24
26
25
// If new predicates were added then we need to re-calculate
27
26
// all crates since there could be new implied predicates.
28
- while predicates_added {
29
- predicates_added = false ;
27
+ ' outer : loop {
28
+ let mut predicates_added = false ;
30
29
31
30
// Visit all the crates and infer predicates
32
31
for id in tcx. hir ( ) . items ( ) {
@@ -53,9 +52,9 @@ pub fn infer_predicates<'tcx>(
53
52
tcx,
54
53
field_ty,
55
54
field_span,
56
- & mut global_inferred_outlives,
55
+ & global_inferred_outlives,
57
56
& mut item_required_predicates,
58
- explicit_map,
57
+ & mut explicit_map,
59
58
) ;
60
59
}
61
60
}
@@ -70,12 +69,17 @@ pub fn infer_predicates<'tcx>(
70
69
// we walk the crates again and re-calculate predicates for all
71
70
// items.
72
71
let item_predicates_len: usize =
73
- global_inferred_outlives. get ( & item_did. to_def_id ( ) ) . map_or ( 0 , |p| p. len ( ) ) ;
72
+ global_inferred_outlives. get ( & item_did. to_def_id ( ) ) . map_or ( 0 , |p| p. 0 . len ( ) ) ;
74
73
if item_required_predicates. len ( ) > item_predicates_len {
75
74
predicates_added = true ;
76
- global_inferred_outlives. insert ( item_did. to_def_id ( ) , item_required_predicates) ;
75
+ global_inferred_outlives
76
+ . insert ( item_did. to_def_id ( ) , ty:: EarlyBinder ( item_required_predicates) ) ;
77
77
}
78
78
}
79
+
80
+ if !predicates_added {
81
+ break ' outer;
82
+ }
79
83
}
80
84
81
85
global_inferred_outlives
@@ -85,7 +89,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
85
89
tcx : TyCtxt < ' tcx > ,
86
90
field_ty : Ty < ' tcx > ,
87
91
field_span : Span ,
88
- global_inferred_outlives : & FxHashMap < DefId , RequiredPredicates < ' tcx > > ,
92
+ global_inferred_outlives : & FxHashMap < DefId , ty :: EarlyBinder < RequiredPredicates < ' tcx > > > ,
89
93
required_predicates : & mut RequiredPredicates < ' tcx > ,
90
94
explicit_map : & mut ExplicitPredicatesMap < ' tcx > ,
91
95
) {
@@ -133,11 +137,13 @@ fn insert_required_predicates_to_be_wf<'tcx>(
133
137
// 'a` holds for `Foo`.
134
138
debug ! ( "Adt" ) ;
135
139
if let Some ( unsubstituted_predicates) = global_inferred_outlives. get ( & def. did ( ) ) {
136
- for ( unsubstituted_predicate, & span) in unsubstituted_predicates {
140
+ for ( unsubstituted_predicate, & span) in & unsubstituted_predicates. 0 {
137
141
// `unsubstituted_predicate` is `U: 'b` in the
138
142
// example above. So apply the substitution to
139
143
// get `T: 'a` (or `predicate`):
140
- let predicate = EarlyBinder ( * unsubstituted_predicate) . subst ( tcx, substs) ;
144
+ let predicate = unsubstituted_predicates
145
+ . rebind ( * unsubstituted_predicate)
146
+ . subst ( tcx, substs) ;
141
147
insert_outlives_predicate (
142
148
tcx,
143
149
predicate. 0 ,
@@ -224,7 +230,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
224
230
/// will give us `U: 'static` and `U: Foo`. The latter we
225
231
/// can ignore, but we will want to process `U: 'static`,
226
232
/// applying the substitution as above.
227
- pub fn check_explicit_predicates < ' tcx > (
233
+ fn check_explicit_predicates < ' tcx > (
228
234
tcx : TyCtxt < ' tcx > ,
229
235
def_id : DefId ,
230
236
substs : & [ GenericArg < ' tcx > ] ,
@@ -242,7 +248,7 @@ pub fn check_explicit_predicates<'tcx>(
242
248
) ;
243
249
let explicit_predicates = explicit_map. explicit_predicates_of ( tcx, def_id) ;
244
250
245
- for ( outlives_predicate, & span) in explicit_predicates {
251
+ for ( outlives_predicate, & span) in & explicit_predicates. 0 {
246
252
debug ! ( "outlives_predicate = {:?}" , & outlives_predicate) ;
247
253
248
254
// Careful: If we are inferring the effects of a `dyn Trait<..>`
@@ -287,7 +293,7 @@ pub fn check_explicit_predicates<'tcx>(
287
293
continue ;
288
294
}
289
295
290
- let predicate = EarlyBinder ( * outlives_predicate) . subst ( tcx, substs) ;
296
+ let predicate = explicit_predicates . rebind ( * outlives_predicate) . subst ( tcx, substs) ;
291
297
debug ! ( "predicate = {:?}" , & predicate) ;
292
298
insert_outlives_predicate ( tcx, predicate. 0 , predicate. 1 , span, required_predicates) ;
293
299
}
0 commit comments