// Finally we register each of these predicates as an obligation in
// a fresh FulfillmentCtxt, and invoke select_all_or_error.
- // Create a parameter environment that represents the implementation's
- // method.
- let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_m_node_id);
-
// Create mapping from impl to skolemized.
- let impl_to_skol_substs = &impl_param_env.free_substs;
+ let impl_to_skol_substs = Substs::identity_for_item(tcx, impl_m.def_id);
// Create mapping from trait to skolemized.
let trait_to_skol_substs = impl_to_skol_substs.rebase_onto(tcx,
impl_m.container.id(),
- trait_to_impl_substs.subst(tcx,
- impl_to_skol_substs));
+ trait_to_impl_substs);
debug!("compare_impl_method: trait_to_skol_substs={:?}",
trait_to_skol_substs);
impl_m,
&trait_m_generics,
&impl_m_generics,
- trait_to_skol_substs,
- impl_to_skol_substs)?;
+ trait_to_skol_substs)?;
// Create obligations for each predicate declared by the impl
// definition in the context of the trait's parameter
// however, because we want to replace all late-bound regions with
// region variables.
let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap());
- let mut hybrid_preds = impl_predicates.instantiate(tcx, impl_to_skol_substs);
+ let mut hybrid_preds = impl_predicates.instantiate_identity(tcx);
debug!("compare_impl_method: impl_bounds={:?}", hybrid_preds);
// The key step here is to update the caller_bounds's predicates to be
// the new hybrid bounds we computed.
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
- let trait_param_env = impl_param_env.with_caller_bounds(
- tcx.intern_predicates(&hybrid_preds.predicates));
- let trait_param_env = traits::normalize_param_env_or_error(tcx,
- impl_m.def_id,
- trait_param_env,
- normalize_cause.clone());
-
- tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| {
- let inh = Inherited::new(infcx);
+ let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates),
+ Reveal::UserFacing);
+ let param_env = traits::normalize_param_env_or_error(tcx,
+ impl_m.def_id,
+ param_env,
+ normalize_cause.clone());
+
+ tcx.infer_ctxt(param_env).enter(|infcx| {
+ let inh = Inherited::new(infcx, impl_m.def_id);
let infcx = &inh.infcx;
debug!("compare_impl_method: caller_bounds={:?}",
- infcx.parameter_environment.caller_bounds);
+ infcx.param_env.caller_bounds);
let mut selcx = traits::SelectionContext::new(&infcx);
infcx.replace_late_bound_regions_with_fresh_var(impl_m_span,
infer::HigherRankedType,
&m_sig(impl_m));
- let impl_sig =
- impl_sig.subst(tcx, impl_to_skol_substs);
let impl_sig =
inh.normalize_associated_types_in(impl_m_span,
impl_m_node_id,
let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
- let trait_sig = tcx.liberate_late_bound_regions(
- infcx.parameter_environment.free_id_outlive,
+ let trait_sig = inh.liberate_late_bound_regions(
+ impl_m.def_id,
&m_sig(trait_m));
let trait_sig =
trait_sig.subst(tcx, trait_to_skol_substs);
let region_maps = RegionMaps::new();
let mut free_regions = FreeRegionMap::new();
free_regions.relate_free_regions_from_predicates(
- &infcx.parameter_environment.caller_bounds);
+ &infcx.param_env.caller_bounds);
infcx.resolve_regions_and_report_errors(impl_m.def_id, ®ion_maps, &free_regions);
} else {
let fcx = FnCtxt::new(&inh, impl_m_node_id);
impl_m: &ty::AssociatedItem,
trait_generics: &ty::Generics,
impl_generics: &ty::Generics,
- trait_to_skol_substs: &Substs<'tcx>,
- impl_to_skol_substs: &Substs<'tcx>)
+ trait_to_skol_substs: &Substs<'tcx>)
-> Result<(), ErrorReported> {
let trait_params = &trait_generics.regions[..];
let impl_params = &impl_generics.regions[..];
debug!("check_region_bounds_on_impl_method: \
trait_generics={:?} \
impl_generics={:?} \
- trait_to_skol_substs={:?} \
- impl_to_skol_substs={:?}",
+ trait_to_skol_substs={:?}",
trait_generics,
impl_generics,
- trait_to_skol_substs,
- impl_to_skol_substs);
+ trait_to_skol_substs);
// Must have same number of early-bound lifetime parameters.
// Unfortunately, if the user screws up the bounds, then this
impl_trait_ref: ty::TraitRef<'tcx>) {
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
- tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
- let inh = Inherited::new(infcx);
+ tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
+ let inh = Inherited::new(infcx, impl_c.def_id);
let infcx = &inh.infcx;
// The below is for the most part highly similar to the procedure
// Create a parameter environment that represents the implementation's
// method.
let impl_c_node_id = tcx.hir.as_local_node_id(impl_c.def_id).unwrap();
- let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_c_node_id);
-
- // Create mapping from impl to skolemized.
- let impl_to_skol_substs = &impl_param_env.free_substs;
-
- // Create mapping from trait to skolemized.
- let trait_to_skol_substs = impl_to_skol_substs.rebase_onto(tcx,
- impl_c.container.id(),
- trait_to_impl_substs.subst(tcx,
- impl_to_skol_substs));
- debug!("compare_const_impl: trait_to_skol_substs={:?}",
- trait_to_skol_substs);
// Compute skolemized form of impl and trait const tys.
- let impl_ty = tcx.type_of(impl_c.def_id).subst(tcx, impl_to_skol_substs);
- let trait_ty = tcx.type_of(trait_c.def_id).subst(tcx, trait_to_skol_substs);
+ let impl_ty = tcx.type_of(impl_c.def_id);
+ let trait_ty = tcx.type_of(trait_c.def_id).subst(tcx, trait_to_impl_substs);
let mut cause = ObligationCause::misc(impl_c_span, impl_c_node_id);
// There is no "body" here, so just pass dummy id.
diag.emit();
}
- // FIXME(#41323) Check the obligations in the fulfillment context.
+ // Check that all obligations are satisfied by the implementation's
+ // version.
+ if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
+ infcx.report_fulfillment_errors(errors);
+ return;
+ }
+
+ let fcx = FnCtxt::new(&inh, impl_c_node_id);
+ fcx.regionck_item(impl_c_node_id, impl_c_span, &[]);
});
}