@@ -88,12 +88,12 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
88
88
ty:: FnPtr ( ..) |
89
89
ty:: Tuple ( ..) |
90
90
ty:: Never |
91
- ty:: Param ( ..) => ( ) ,
91
+ ty:: Infer ( ..) |
92
+ ty:: Bound ( ..) => ( ) ,
92
93
93
94
ty:: GeneratorWitness ( ..) |
94
95
ty:: UnnormalizedProjection ( ..) |
95
- ty:: Infer ( ..) |
96
- ty:: Bound ( ..) |
96
+ ty:: Param ( ..) |
97
97
ty:: Error => {
98
98
bug ! ( "unexpected type {:?}" , ty) ;
99
99
}
@@ -173,21 +173,28 @@ crate fn program_clauses_for_env<'a, 'tcx>(
173
173
) ;
174
174
}
175
175
176
- crate fn environment < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> Environment < ' tcx > {
176
+ crate fn environment < ' a , ' tcx > (
177
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
178
+ def_id : DefId
179
+ ) -> ty:: Binder < Environment < ' tcx > > {
177
180
use super :: { Lower , IntoFromEnvGoal } ;
178
181
use rustc:: hir:: { Node , TraitItemKind , ImplItemKind , ItemKind , ForeignItemKind } ;
182
+ use rustc:: ty:: subst:: { Subst , Substs } ;
179
183
180
184
// The environment of an impl Trait type is its defining function's environment.
181
185
if let Some ( parent) = ty:: is_impl_trait_defn ( tcx, def_id) {
182
186
return environment ( tcx, parent) ;
183
187
}
184
188
189
+ let bound_vars = Substs :: bound_vars_for_item ( tcx, def_id) ;
190
+
185
191
// Compute the bounds on `Self` and the type parameters.
186
- let ty:: InstantiatedPredicates { predicates } =
187
- tcx . predicates_of ( def_id ) . instantiate_identity ( tcx) ;
192
+ let ty:: InstantiatedPredicates { predicates } = tcx . predicates_of ( def_id )
193
+ . instantiate_identity ( tcx) ;
188
194
189
195
let clauses = predicates. into_iter ( )
190
196
. map ( |predicate| predicate. lower ( ) )
197
+ . map ( |predicate| predicate. subst ( tcx, bound_vars) )
191
198
. map ( |domain_goal| domain_goal. map_bound ( |bound| bound. into_from_env_goal ( ) ) )
192
199
. map ( |domain_goal| domain_goal. map_bound ( |bound| bound. into_program_clause ( ) ) )
193
200
@@ -228,33 +235,43 @@ crate fn environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> En
228
235
229
236
let mut input_tys = FxHashSet :: default ( ) ;
230
237
231
- // In an impl, we assume that the receiver type and all its constituents
238
+ // In an impl, we assume that the header trait ref and all its constituents
232
239
// are well-formed.
233
240
if is_impl {
234
- let trait_ref = tcx. impl_trait_ref ( def_id) . expect ( "not an impl" ) ;
235
- input_tys. extend ( trait_ref. self_ty ( ) . walk ( ) ) ;
241
+ let trait_ref = tcx. impl_trait_ref ( def_id)
242
+ . expect ( "not an impl" )
243
+ . subst ( tcx, bound_vars) ;
244
+
245
+ input_tys. extend (
246
+ trait_ref. substs . types ( ) . flat_map ( |ty| ty. walk ( ) )
247
+ ) ;
236
248
}
237
249
238
250
// In an fn, we assume that the arguments and all their constituents are
239
251
// well-formed.
240
252
if is_fn {
241
- let fn_sig = tcx. fn_sig ( def_id) ;
253
+ // `skip_binder` because we move late bound regions to the root binder,
254
+ // restored in the return type
255
+ let fn_sig = tcx. fn_sig ( def_id) . skip_binder ( ) . subst ( tcx, bound_vars) ;
256
+
242
257
input_tys. extend (
243
- // FIXME: `skip_binder` seems ok for now? In a real setting,
244
- // the late bound regions would next be instantiated with things
245
- // in the inference table.
246
- fn_sig. skip_binder ( ) . inputs ( ) . iter ( ) . flat_map ( |ty| ty. walk ( ) )
258
+ fn_sig. inputs ( ) . iter ( ) . flat_map ( |ty| ty. walk ( ) )
247
259
) ;
248
260
}
249
261
250
262
let clauses = clauses. chain (
251
263
input_tys. into_iter ( )
264
+ // Filter out type parameters
265
+ . filter ( |ty| match ty. sty {
266
+ ty:: Bound ( ..) => false ,
267
+ _ => true ,
268
+ } )
252
269
. map ( |ty| DomainGoal :: FromEnv ( FromEnv :: Ty ( ty) ) )
253
270
. map ( |domain_goal| domain_goal. into_program_clause ( ) )
254
271
. map ( Clause :: Implies )
255
272
) ;
256
273
257
- Environment {
274
+ ty :: Binder :: bind ( Environment {
258
275
clauses : tcx. mk_clauses ( clauses) ,
259
- }
276
+ } )
260
277
}
0 commit comments