@@ -99,69 +99,64 @@ pub(super) fn infer_predicates(
99
99
100
100
fn insert_required_predicates_to_be_wf < ' tcx > (
101
101
tcx : TyCtxt < ' tcx > ,
102
- field_ty : Ty < ' tcx > ,
103
- field_span : Span ,
102
+ ty : Ty < ' tcx > ,
103
+ span : Span ,
104
104
global_inferred_outlives : & FxHashMap < DefId , ty:: EarlyBinder < RequiredPredicates < ' tcx > > > ,
105
105
required_predicates : & mut RequiredPredicates < ' tcx > ,
106
106
explicit_map : & mut ExplicitPredicatesMap < ' tcx > ,
107
107
) {
108
- for arg in field_ty . walk ( ) {
109
- let ty = match arg. unpack ( ) {
108
+ for arg in ty . walk ( ) {
109
+ let leaf_ty = match arg. unpack ( ) {
110
110
GenericArgKind :: Type ( ty) => ty,
111
111
112
112
// No predicates from lifetimes or constants, except potentially
113
113
// constants' types, but `walk` will get to them as well.
114
114
GenericArgKind :: Lifetime ( _) | GenericArgKind :: Const ( _) => continue ,
115
115
} ;
116
116
117
- match * ty . kind ( ) {
118
- // The field is of type &'a T which means that we will have
119
- // a predicate requirement of T: 'a (T outlives 'a ).
117
+ match * leaf_ty . kind ( ) {
118
+ // The type is ` &'a T` which means that we will have
119
+ // a predicate requirement of ` T: 'a` (`T` outlives `'a` ).
120
120
//
121
- // We also want to calculate potential predicates for the T
121
+ // We also want to calculate potential predicates for the `T`.
122
122
ty:: Ref ( region, rty, _) => {
123
123
debug ! ( "Ref" ) ;
124
- insert_outlives_predicate ( tcx, rty. into ( ) , region, field_span , required_predicates) ;
124
+ insert_outlives_predicate ( tcx, rty. into ( ) , region, span , required_predicates) ;
125
125
}
126
126
127
- // For each Adt (struct/enum/union) type `Foo<'a, T>`, we
128
- // can load the current set of inferred and explicit
129
- // predicates from `global_inferred_outlives` and filter the
130
- // ones that are TypeOutlives.
127
+ // For each outer type `Outer<'a, T>`, we can load the current set of
128
+ // inferred and explicit predicates from `global_inferred_outlives` and
129
+ // filter the ones that are `TypeOutlives`.
131
130
ty:: Adt ( def, args) => {
132
131
// First check the inferred predicates
133
132
//
134
- // Example 1 :
133
+ // Example:
135
134
//
136
- // struct Foo <'a, T> {
137
- // field1: Bar <'a, T>
135
+ // struct Outer <'a, T> {
136
+ // outer: Inner <'a, T>
138
137
// }
139
138
//
140
- // struct Bar <'b, U> {
141
- // field2 : &'b U
139
+ // struct Inner <'b, U> {
140
+ // inner : &'b U
142
141
// }
143
142
//
144
- // Here, when processing the type of `field1 `, we would
145
- // request the set of implicit predicates computed for `Bar `
143
+ // Here, when processing the type of field `outer `, we would
144
+ // request the set of implicit predicates computed for `Inner `
146
145
// thus far. This will initially come back empty, but in next
147
146
// round we will get `U: 'b`. We then apply the substitution
148
147
// `['b => 'a, U => T]` and thus get the requirement that `T:
149
- // 'a` holds for `Foo `.
148
+ // 'a` holds for `Outer `.
150
149
debug ! ( "Adt" ) ;
151
- if let Some ( unsubstituted_predicates) = global_inferred_outlives. get ( & def. did ( ) ) {
152
- for ( unsubstituted_predicate, & span) in
153
- unsubstituted_predicates. as_ref ( ) . skip_binder ( )
154
- {
155
- // `unsubstituted_predicate` is `U: 'b` in the
156
- // example above. So apply the substitution to
157
- // get `T: 'a` (or `predicate`):
158
- let predicate = unsubstituted_predicates
159
- . rebind ( * unsubstituted_predicate)
160
- . instantiate ( tcx, args) ;
150
+ if let Some ( predicates) = global_inferred_outlives. get ( & def. did ( ) ) {
151
+ for ( predicate, & span) in predicates. as_ref ( ) . skip_binder ( ) {
152
+ // `predicate` is `U: 'b` in the example above. So apply the
153
+ // substitution to get `T: 'a` (or `instantiated_predicate`):
154
+ let instantiated_predicate =
155
+ predicates. rebind ( * predicate) . instantiate ( tcx, args) ;
161
156
insert_outlives_predicate (
162
157
tcx,
163
- predicate . 0 ,
164
- predicate . 1 ,
158
+ instantiated_predicate . 0 ,
159
+ instantiated_predicate . 1 ,
165
160
span,
166
161
required_predicates,
167
162
) ;
@@ -170,7 +165,6 @@ fn insert_required_predicates_to_be_wf<'tcx>(
170
165
171
166
// Check if the type has any explicit predicates that need
172
167
// to be added to `required_predicates`
173
- // let _: () = args.region_at(0);
174
168
check_explicit_predicates (
175
169
tcx,
176
170
def. did ( ) ,
@@ -184,10 +178,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
184
178
ty:: Dynamic ( obj, ..) => {
185
179
// This corresponds to `dyn Trait<..>`. In this case, we should
186
180
// use the explicit predicates as well.
187
-
188
181
debug ! ( "Dynamic" ) ;
189
- debug ! ( "field_ty = {}" , & field_ty) ;
190
- debug ! ( "ty in field = {}" , & ty) ;
191
182
if let Some ( ex_trait_ref) = obj. principal ( ) {
192
183
// Here, we are passing the type `usize` as a
193
184
// placeholder value with the function
@@ -209,14 +200,15 @@ fn insert_required_predicates_to_be_wf<'tcx>(
209
200
}
210
201
}
211
202
212
- ty:: Alias ( ty:: Projection , obj) => {
213
- // This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
214
- // explicit predicates as well.
203
+ ty:: Alias ( ty:: Projection , alias) => {
204
+ // This corresponds to a type like `<() as Trait<'a, T>>::Type`.
205
+ // We only use the explicit predicates of the trait but
206
+ // not the ones of the associated type itself.
215
207
debug ! ( "Projection" ) ;
216
208
check_explicit_predicates (
217
209
tcx,
218
- tcx. parent ( obj . def_id ) ,
219
- obj . args ,
210
+ tcx. parent ( alias . def_id ) ,
211
+ alias . args ,
220
212
required_predicates,
221
213
explicit_map,
222
214
None ,
@@ -238,7 +230,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
238
230
) ;
239
231
}
240
232
241
- // FIXME(inherent_associated_types): Handle this case properly .
233
+ // FIXME(inherent_associated_types): Use the explicit predicates from the parent impl .
242
234
ty:: Alias ( ty:: Inherent , _) => { }
243
235
244
236
_ => { }
0 commit comments