@@ -177,37 +177,61 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
177
177
let impl_env = ty:: ParameterEnvironment :: for_item ( tcx, impl_m. def_id . node ) ;
178
178
179
179
// Create mapping from impl to skolemized.
180
- let impl_to_skol_substs = impl_env. free_substs . clone ( ) ;
180
+ let impl_to_skol_substs = & impl_env. free_substs ;
181
181
182
182
// Create mapping from trait to skolemized.
183
183
let trait_to_skol_substs =
184
184
trait_to_impl_substs
185
- . subst ( tcx, & impl_to_skol_substs)
185
+ . subst ( tcx, impl_to_skol_substs)
186
186
. with_method ( impl_to_skol_substs. types . get_slice ( subst:: FnSpace ) . to_vec ( ) ,
187
187
impl_to_skol_substs. regions ( ) . get_slice ( subst:: FnSpace ) . to_vec ( ) ) ;
188
+ debug ! ( "compare_impl_method: trait_to_skol_substs={}" ,
189
+ trait_to_skol_substs. repr( tcx) ) ;
190
+
191
+ // Construct trait parameter environment and then shift it into the skolemized viewpoint.
192
+ let trait_param_env =
193
+ ty:: construct_parameter_environment ( tcx,
194
+ & trait_m. generics ,
195
+ impl_m_body_id) ;
196
+ let trait_param_env =
197
+ trait_param_env. subst ( tcx, & trait_to_skol_substs) ;
198
+ debug ! ( "compare_impl_method: trait_param_env={}" ,
199
+ trait_param_env. repr( tcx) ) ;
188
200
189
201
// Create a fresh fulfillment context.
190
202
let mut fulfill_cx = traits:: FulfillmentContext :: new ( ) ;
191
203
192
- // Create obligations for each predicate declared by the trait definition.
193
- for predicate in trait_m. generics . predicates . iter ( )
194
- . map ( |p| p. subst ( tcx, & trait_to_skol_substs) ) {
204
+ // Create obligations for each predicate declared by the impl
205
+ // definition in the context of the trait's parameter
206
+ // environment. We can't just use `impl_env.caller_bounds`,
207
+ // however, because we want to replace all late-bound regions with
208
+ // region variables.
209
+ let impl_bounds =
210
+ impl_m. generics . to_bounds ( tcx, impl_to_skol_substs) ;
211
+ let ( impl_bounds, _) =
212
+ infcx. replace_late_bound_regions_with_fresh_var (
213
+ impl_m_span,
214
+ infer:: HigherRankedType ,
215
+ & ty:: Binder ( impl_bounds) ) ; // TODO I think this is right?
216
+ debug ! ( "compare_impl_method: impl_bounds={}" ,
217
+ impl_bounds. repr( tcx) ) ;
218
+ for predicate in impl_bounds. predicates . into_iter ( ) {
195
219
fulfill_cx. register_predicate (
196
220
tcx,
197
- traits:: Obligation :: new ( traits:: ObligationCause :: dummy ( ) , predicate )
198
- )
221
+ traits:: Obligation :: new ( traits:: ObligationCause :: dummy ( ) ,
222
+ predicate ) ) ;
199
223
}
200
224
201
225
// Check that all obligations are satisfied by the implementation's
202
226
// version.
203
- match fulfill_cx. select_all_or_error ( & infcx, & impl_env , tcx) {
227
+ match fulfill_cx. select_all_or_error ( & infcx, & trait_param_env , tcx) {
204
228
Err ( ref errors) => { traits:: report_fulfillment_errors ( & infcx, errors) }
205
229
Ok ( _) => { }
206
230
}
207
231
208
232
// Compute skolemized form of impl and trait method tys.
209
233
let impl_fty = ty:: mk_bare_fn ( tcx, None , impl_m. fty . clone ( ) ) ;
210
- let impl_fty = impl_fty. subst ( tcx, & impl_to_skol_substs) ;
234
+ let impl_fty = impl_fty. subst ( tcx, impl_to_skol_substs) ;
211
235
let trait_fty = ty:: mk_bare_fn ( tcx, None , trait_m. fty . clone ( ) ) ;
212
236
let trait_fty = trait_fty. subst ( tcx, & trait_to_skol_substs) ;
213
237
0 commit comments