Skip to content

Commit 2846d6f

Browse files
authored
Rollup merge of rust-lang#104903 - spastorino:consolidate-normalize-in-report_projection_error, r=lcnr
Use ocx.normalize in report_projection_error r? `@lcnr` cc `@compiler-errors`
2 parents e960b5e + 190e7bd commit 2846d6f

File tree

2 files changed

+51
-21
lines changed

2 files changed

+51
-21
lines changed

compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,27 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
112112
self.register_infer_ok_obligations(infer_ok)
113113
}
114114

115+
/// Makes `expected <: actual`.
116+
///
117+
/// See [`At::trace_exp`] and [`Trace::eq`] for a version of
118+
/// this method that only requires `T: Relate<'tcx>`
119+
pub fn eq_exp<T>(
120+
&self,
121+
cause: &ObligationCause<'tcx>,
122+
param_env: ty::ParamEnv<'tcx>,
123+
a_is_expected: bool,
124+
a: T,
125+
b: T,
126+
) -> Result<(), TypeError<'tcx>>
127+
where
128+
T: ToTrace<'tcx>,
129+
{
130+
self.infcx
131+
.at(cause, param_env)
132+
.eq_exp(a_is_expected, a, b)
133+
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
134+
}
135+
115136
pub fn eq<T: ToTrace<'tcx>>(
116137
&self,
117138
cause: &ObligationCause<'tcx>,

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,32 +1577,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15771577
}
15781578

15791579
self.probe(|_| {
1580-
let mut err = error.err;
1581-
let mut values = None;
1580+
let ocx = ObligationCtxt::new_in_snapshot(self);
15821581

15831582
// try to find the mismatched types to report the error with.
15841583
//
15851584
// this can fail if the problem was higher-ranked, in which
15861585
// cause I have no idea for a good error message.
15871586
let bound_predicate = predicate.kind();
1588-
if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
1587+
let (values, err) = if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
15891588
bound_predicate.skip_binder()
15901589
{
1591-
let mut selcx = SelectionContext::new(self);
15921590
let data = self.replace_bound_vars_with_fresh_vars(
15931591
obligation.cause.span,
15941592
infer::LateBoundRegionConversionTime::HigherRankedType,
15951593
bound_predicate.rebind(data),
15961594
);
1597-
let mut obligations = vec![];
1598-
// FIXME(normalization): Change this to use `At::normalize`
1599-
let normalized_ty = super::normalize_projection_type(
1600-
&mut selcx,
1595+
let normalized_ty = ocx.normalize(
1596+
&obligation.cause,
16011597
obligation.param_env,
1602-
data.projection_ty,
1603-
obligation.cause.clone(),
1604-
0,
1605-
&mut obligations,
1598+
self.tcx
1599+
.mk_projection(data.projection_ty.item_def_id, data.projection_ty.substs),
16061600
);
16071601

16081602
debug!(?obligation.cause, ?obligation.param_env);
@@ -1618,19 +1612,34 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16181612
| ObligationCauseCode::ObjectCastObligation(..)
16191613
| ObligationCauseCode::OpaqueType
16201614
);
1621-
if let Err(new_err) = self.at(&obligation.cause, obligation.param_env).eq_exp(
1615+
let expected_ty = data.term.ty().unwrap();
1616+
1617+
// constrain inference variables a bit more to nested obligations from normalize so
1618+
// we can have more helpful errors.
1619+
ocx.select_where_possible();
1620+
1621+
if let Err(new_err) = ocx.eq_exp(
1622+
&obligation.cause,
1623+
obligation.param_env,
16221624
is_normalized_ty_expected,
16231625
normalized_ty,
1624-
data.term,
1626+
expected_ty,
16251627
) {
1626-
values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
1627-
err = new_err;
1628+
(Some((data, is_normalized_ty_expected, normalized_ty, expected_ty)), new_err)
1629+
} else {
1630+
(None, error.err)
16281631
}
1629-
}
1632+
} else {
1633+
(None, error.err)
1634+
};
16301635

16311636
let msg = values
16321637
.and_then(|(predicate, _, normalized_ty, expected_ty)| {
1633-
self.maybe_detailed_projection_msg(predicate, normalized_ty, expected_ty)
1638+
self.maybe_detailed_projection_msg(
1639+
predicate,
1640+
normalized_ty.into(),
1641+
expected_ty.into(),
1642+
)
16341643
})
16351644
.unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
16361645
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> {
16721681
&mut diag,
16731682
&obligation.cause,
16741683
secondary_span,
1675-
values.map(|(_, is_normalized_ty_expected, normalized_ty, term)| {
1684+
values.map(|(_, is_normalized_ty_expected, normalized_ty, expected_ty)| {
16761685
infer::ValuePairs::Terms(ExpectedFound::new(
16771686
is_normalized_ty_expected,
1678-
normalized_ty,
1679-
term,
1687+
normalized_ty.into(),
1688+
expected_ty.into(),
16801689
))
16811690
}),
16821691
err,

0 commit comments

Comments
 (0)