@@ -88,12 +88,12 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
8888 ty:: FnPtr ( ..) |
8989 ty:: Tuple ( ..) |
9090 ty:: Never |
91- ty:: Param ( ..) => ( ) ,
91+ ty:: Infer ( ..) |
92+ ty:: Bound ( ..) => ( ) ,
9293
9394 ty:: GeneratorWitness ( ..) |
9495 ty:: UnnormalizedProjection ( ..) |
95- ty:: Infer ( ..) |
96- ty:: Bound ( ..) |
96+ ty:: Param ( ..) |
9797 ty:: Error => {
9898 bug ! ( "unexpected type {:?}" , ty) ;
9999 }
@@ -173,21 +173,28 @@ crate fn program_clauses_for_env<'a, 'tcx>(
173173 ) ;
174174}
175175
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 > > {
177180 use super :: { Lower , IntoFromEnvGoal } ;
178181 use rustc:: hir:: { Node , TraitItemKind , ImplItemKind , ItemKind , ForeignItemKind } ;
182+ use rustc:: ty:: subst:: { Subst , Substs } ;
179183
180184 // The environment of an impl Trait type is its defining function's environment.
181185 if let Some ( parent) = ty:: is_impl_trait_defn ( tcx, def_id) {
182186 return environment ( tcx, parent) ;
183187 }
184188
189+ let bound_vars = Substs :: bound_vars_for_item ( tcx, def_id) ;
190+
185191 // 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) ;
188194
189195 let clauses = predicates. into_iter ( )
190196 . map ( |predicate| predicate. lower ( ) )
197+ . map ( |predicate| predicate. subst ( tcx, bound_vars) )
191198 . map ( |domain_goal| domain_goal. map_bound ( |bound| bound. into_from_env_goal ( ) ) )
192199 . map ( |domain_goal| domain_goal. map_bound ( |bound| bound. into_program_clause ( ) ) )
193200
@@ -228,33 +235,43 @@ crate fn environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> En
228235
229236 let mut input_tys = FxHashSet :: default ( ) ;
230237
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
232239 // are well-formed.
233240 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+ ) ;
236248 }
237249
238250 // In an fn, we assume that the arguments and all their constituents are
239251 // well-formed.
240252 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+
242257 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 ( ) )
247259 ) ;
248260 }
249261
250262 let clauses = clauses. chain (
251263 input_tys. into_iter ( )
264+ // Filter out type parameters
265+ . filter ( |ty| match ty. sty {
266+ ty:: Bound ( ..) => false ,
267+ _ => true ,
268+ } )
252269 . map ( |ty| DomainGoal :: FromEnv ( FromEnv :: Ty ( ty) ) )
253270 . map ( |domain_goal| domain_goal. into_program_clause ( ) )
254271 . map ( Clause :: Implies )
255272 ) ;
256273
257- Environment {
274+ ty :: Binder :: bind ( Environment {
258275 clauses : tcx. mk_clauses ( clauses) ,
259- }
276+ } )
260277}
0 commit comments