// 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 = tcx.parameter_environment(impl_m.def_id);
-
// Create mapping from impl to skolemized.
let impl_to_skol_substs = Substs::identity_for_item(tcx, impl_m.def_id);
// 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 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(()).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);
+ param_env.caller_bounds);
let mut selcx = traits::SelectionContext::new(&infcx);
&ty::Binder(impl_m_own_bounds.predicates));
for predicate in impl_m_own_bounds {
let traits::Normalized { value: predicate, obligations } =
- traits::normalize(&mut selcx, normalize_cause.clone(), &predicate);
+ traits::normalize(&mut selcx, param_env, normalize_cause.clone(), &predicate);
inh.register_predicates(obligations);
- inh.register_predicate(traits::Obligation::new(cause.clone(), predicate));
+ inh.register_predicate(traits::Obligation::new(cause.clone(), param_env, predicate));
}
// We now need to check that the signature of the impl method is
let impl_sig =
inh.normalize_associated_types_in(impl_m_span,
impl_m_node_id,
+ param_env,
&impl_sig);
let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
let trait_sig =
inh.normalize_associated_types_in(impl_m_span,
impl_m_node_id,
+ param_env,
&trait_sig);
let trait_fty = tcx.mk_fn_ptr(ty::Binder(trait_sig));
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
- let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
+ let sub_result = infcx.at(&cause, param_env)
+ .sup(trait_fty, impl_fty)
.map(|InferOk { obligations, .. }| {
inh.register_predicates(obligations);
});
trait_fty);
let (impl_err_span, trait_err_span) = extract_spans_for_error_reporting(&infcx,
+ param_env,
&terr,
&cause,
impl_m,
// pass around temporarily.
let region_maps = RegionMaps::new();
let mut free_regions = FreeRegionMap::new();
- free_regions.relate_free_regions_from_predicates(
- &infcx.parameter_environment.caller_bounds);
+ free_regions.relate_free_regions_from_predicates(¶m_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);
+ let fcx = FnCtxt::new(&inh, param_env, impl_m_node_id);
fcx.regionck_item(impl_m_node_id, impl_m_span, &[]);
}
}
fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
terr: &TypeError,
cause: &ObligationCause<'tcx>,
impl_m: &ty::AssociatedItem,
impl_iter.zip(trait_iter)
.zip(impl_m_iter)
.zip(trait_m_iter)
- .filter_map(|(((impl_arg_ty, trait_arg_ty), impl_arg), trait_arg)| {
- match infcx.sub_types(true, &cause, trait_arg_ty, impl_arg_ty) {
+ .filter_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| {
+ match infcx.at(&cause, param_env).sub(trait_arg_ty, impl_arg_ty) {
Ok(_) => None,
Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
}
})
.next()
.unwrap_or_else(|| {
- if infcx.sub_types(false, &cause, impl_sig.output(),
- trait_sig.output())
- .is_err() {
- (impl_m_output.span(), Some(trait_m_output.span()))
- } else {
- (cause.span, tcx.hir.span_if_local(trait_m.def_id))
- }
+ if
+ infcx.at(&cause, param_env)
+ .sup(trait_sig.output(), impl_sig.output())
+ .is_err()
+ {
+ (impl_m_output.span(), Some(trait_m_output.span()))
+ } else {
+ (cause.span, tcx.hir.span_if_local(trait_m.def_id))
+ }
})
} else {
(cause.span, tcx.hir.span_if_local(trait_m.def_id))
format!("expected `{}` in impl", self_descr));
if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) {
err.span_label(span, format!("`{}` used in trait", self_descr));
+ } else {
+ err.note_trait_signature(trait_m.name.to_string(),
+ trait_m.signature(&tcx));
}
err.emit();
return Err(ErrorReported);
} else {
format!("{} parameter", trait_number_args)
}));
+ } else {
+ err.note_trait_signature(trait_m.name.to_string(),
+ trait_m.signature(&tcx));
}
err.span_label(impl_span,
format!("expected {}, found {}",
impl_trait_ref: ty::TraitRef<'tcx>) {
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
- tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+ tcx.infer_ctxt(()).enter(|infcx| {
+ let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let inh = Inherited::new(infcx, impl_c.def_id);
let infcx = &inh.infcx;
// There is no "body" here, so just pass dummy id.
let impl_ty = inh.normalize_associated_types_in(impl_c_span,
impl_c_node_id,
+ param_env,
&impl_ty);
debug!("compare_const_impl: impl_ty={:?}", impl_ty);
let trait_ty = inh.normalize_associated_types_in(impl_c_span,
impl_c_node_id,
+ param_env,
&trait_ty);
debug!("compare_const_impl: trait_ty={:?}", trait_ty);
- let err = infcx.sub_types(false, &cause, impl_ty, trait_ty)
- .map(|ok| inh.register_infer_ok_obligations(ok));
+ let err = infcx.at(&cause, param_env)
+ .sup(trait_ty, impl_ty)
+ .map(|ok| inh.register_infer_ok_obligations(ok));
if let Err(terr) = err {
debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
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, param_env, impl_c_node_id);
+ fcx.regionck_item(impl_c_node_id, impl_c_span, &[]);
});
}