Rollup merge of #104903 - spastorino:consolidate-normalize-in-report_projection_error, r=lcnr
Use ocx.normalize in report_projection_error r? `@lcnr` cc `@compiler-errors`
This commit is contained in:
commit
52e886279a
2 changed files with 48 additions and 21 deletions
|
@ -112,6 +112,24 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
|
||||||
self.register_infer_ok_obligations(infer_ok)
|
self.register_infer_ok_obligations(infer_ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Makes `expected <: actual`.
|
||||||
|
pub fn eq_exp<T>(
|
||||||
|
&self,
|
||||||
|
cause: &ObligationCause<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
a_is_expected: bool,
|
||||||
|
a: T,
|
||||||
|
b: T,
|
||||||
|
) -> Result<(), TypeError<'tcx>>
|
||||||
|
where
|
||||||
|
T: ToTrace<'tcx>,
|
||||||
|
{
|
||||||
|
self.infcx
|
||||||
|
.at(cause, param_env)
|
||||||
|
.eq_exp(a_is_expected, a, b)
|
||||||
|
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eq<T: ToTrace<'tcx>>(
|
pub fn eq<T: ToTrace<'tcx>>(
|
||||||
&self,
|
&self,
|
||||||
cause: &ObligationCause<'tcx>,
|
cause: &ObligationCause<'tcx>,
|
||||||
|
|
|
@ -1577,32 +1577,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.probe(|_| {
|
self.probe(|_| {
|
||||||
let mut err = error.err;
|
let ocx = ObligationCtxt::new_in_snapshot(self);
|
||||||
let mut values = None;
|
|
||||||
|
|
||||||
// try to find the mismatched types to report the error with.
|
// try to find the mismatched types to report the error with.
|
||||||
//
|
//
|
||||||
// this can fail if the problem was higher-ranked, in which
|
// this can fail if the problem was higher-ranked, in which
|
||||||
// cause I have no idea for a good error message.
|
// cause I have no idea for a good error message.
|
||||||
let bound_predicate = predicate.kind();
|
let bound_predicate = predicate.kind();
|
||||||
if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
|
let (values, err) = if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
|
||||||
bound_predicate.skip_binder()
|
bound_predicate.skip_binder()
|
||||||
{
|
{
|
||||||
let mut selcx = SelectionContext::new(self);
|
|
||||||
let data = self.replace_bound_vars_with_fresh_vars(
|
let data = self.replace_bound_vars_with_fresh_vars(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
infer::LateBoundRegionConversionTime::HigherRankedType,
|
infer::LateBoundRegionConversionTime::HigherRankedType,
|
||||||
bound_predicate.rebind(data),
|
bound_predicate.rebind(data),
|
||||||
);
|
);
|
||||||
let mut obligations = vec![];
|
let normalized_ty = ocx.normalize(
|
||||||
// FIXME(normalization): Change this to use `At::normalize`
|
&obligation.cause,
|
||||||
let normalized_ty = super::normalize_projection_type(
|
|
||||||
&mut selcx,
|
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
data.projection_ty,
|
self.tcx
|
||||||
obligation.cause.clone(),
|
.mk_projection(data.projection_ty.item_def_id, data.projection_ty.substs),
|
||||||
0,
|
|
||||||
&mut obligations,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(?obligation.cause, ?obligation.param_env);
|
debug!(?obligation.cause, ?obligation.param_env);
|
||||||
|
@ -1618,19 +1612,34 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
| ObligationCauseCode::ObjectCastObligation(..)
|
| ObligationCauseCode::ObjectCastObligation(..)
|
||||||
| ObligationCauseCode::OpaqueType
|
| ObligationCauseCode::OpaqueType
|
||||||
);
|
);
|
||||||
if let Err(new_err) = self.at(&obligation.cause, obligation.param_env).eq_exp(
|
let expected_ty = data.term.ty().unwrap();
|
||||||
|
|
||||||
|
// constrain inference variables a bit more to nested obligations from normalize so
|
||||||
|
// we can have more helpful errors.
|
||||||
|
ocx.select_where_possible();
|
||||||
|
|
||||||
|
if let Err(new_err) = ocx.eq_exp(
|
||||||
|
&obligation.cause,
|
||||||
|
obligation.param_env,
|
||||||
is_normalized_ty_expected,
|
is_normalized_ty_expected,
|
||||||
normalized_ty,
|
normalized_ty,
|
||||||
data.term,
|
expected_ty,
|
||||||
) {
|
) {
|
||||||
values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
|
(Some((data, is_normalized_ty_expected, normalized_ty, expected_ty)), new_err)
|
||||||
err = new_err;
|
} else {
|
||||||
|
(None, error.err)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
(None, error.err)
|
||||||
|
};
|
||||||
|
|
||||||
let msg = values
|
let msg = values
|
||||||
.and_then(|(predicate, _, normalized_ty, expected_ty)| {
|
.and_then(|(predicate, _, normalized_ty, expected_ty)| {
|
||||||
self.maybe_detailed_projection_msg(predicate, normalized_ty, expected_ty)
|
self.maybe_detailed_projection_msg(
|
||||||
|
predicate,
|
||||||
|
normalized_ty.into(),
|
||||||
|
expected_ty.into(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
|
.unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
|
||||||
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
|
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
|
||||||
|
@ -1672,11 +1681,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
&mut diag,
|
&mut diag,
|
||||||
&obligation.cause,
|
&obligation.cause,
|
||||||
secondary_span,
|
secondary_span,
|
||||||
values.map(|(_, is_normalized_ty_expected, normalized_ty, term)| {
|
values.map(|(_, is_normalized_ty_expected, normalized_ty, expected_ty)| {
|
||||||
infer::ValuePairs::Terms(ExpectedFound::new(
|
infer::ValuePairs::Terms(ExpectedFound::new(
|
||||||
is_normalized_ty_expected,
|
is_normalized_ty_expected,
|
||||||
normalized_ty,
|
normalized_ty.into(),
|
||||||
term,
|
expected_ty.into(),
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
err,
|
err,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue