Skip to content

Commit cbf9153

Browse files
committed
dont normalize return type during candidate assembly in method probing
1 parent 5641481 commit cbf9153

File tree

1 file changed

+35
-10
lines changed
  • compiler/rustc_typeck/src/check/method

1 file changed

+35
-10
lines changed

compiler/rustc_typeck/src/check/method/probe.rs

+35-10
Original file line numberDiff line numberDiff line change
@@ -753,17 +753,27 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
753753
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
754754
let impl_ty = impl_ty.subst(self.tcx, impl_substs);
755755

756+
debug!("impl_ty: {:?}", impl_ty);
757+
756758
// Determine the receiver type that the method itself expects.
757-
let xform_tys = self.xform_self_ty(&item, impl_ty, impl_substs);
759+
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs);
760+
debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
758761

759762
// We can't use normalize_associated_types_in as it will pollute the
760763
// fcx's fulfillment context after this probe is over.
764+
// Note: we only normalize `xform_self_ty` here since the normalization
765+
// of the return type can lead to inference results that prohibit
766+
// valid canidates from being found, see issue #85671
767+
// FIXME Postponing the normalization of the return type likely only hides a deeper bug,
768+
// which might be caused by the `param_env` itself. The clauses of the `param_env`
769+
// maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
770+
// see isssue #89650
761771
let cause = traits::ObligationCause::misc(self.span, self.body_id);
762772
let selcx = &mut traits::SelectionContext::new(self.fcx);
763-
let traits::Normalized { value: (xform_self_ty, xform_ret_ty), obligations } =
764-
traits::normalize(selcx, self.param_env, cause, xform_tys);
773+
let traits::Normalized { value: xform_self_ty, obligations } =
774+
traits::normalize(selcx, self.param_env, cause, xform_self_ty);
765775
debug!(
766-
"assemble_inherent_impl_probe: xform_self_ty = {:?}/{:?}",
776+
"assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
767777
xform_self_ty, xform_ret_ty
768778
);
769779

@@ -1420,6 +1430,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14201430
};
14211431

14221432
let mut result = ProbeResult::Match;
1433+
let mut xform_ret_ty = probe.xform_ret_ty;
1434+
debug!(?xform_ret_ty);
1435+
14231436
let selcx = &mut traits::SelectionContext::new(self);
14241437
let cause = traits::ObligationCause::misc(self.span, self.body_id);
14251438

@@ -1428,7 +1441,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14281441
// match as well (or at least may match, sometimes we
14291442
// don't have enough information to fully evaluate).
14301443
match probe.kind {
1431-
InherentImplCandidate(substs, ref ref_obligations) => {
1444+
InherentImplCandidate(ref substs, ref ref_obligations) => {
1445+
// `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
1446+
// see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
1447+
// for why this is necessary
1448+
let traits::Normalized {
1449+
value: normalized_xform_ret_ty,
1450+
obligations: normalization_obligations,
1451+
} = traits::normalize(selcx, self.param_env, cause.clone(), probe.xform_ret_ty);
1452+
xform_ret_ty = normalized_xform_ret_ty;
1453+
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
1454+
14321455
// Check whether the impl imposes obligations we have to worry about.
14331456
let impl_def_id = probe.item.container.id();
14341457
let impl_bounds = self.tcx.predicates_of(impl_def_id);
@@ -1442,7 +1465,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14421465

14431466
let candidate_obligations = impl_obligations
14441467
.chain(norm_obligations.into_iter())
1445-
.chain(ref_obligations.iter().cloned());
1468+
.chain(ref_obligations.iter().cloned())
1469+
.chain(normalization_obligations.into_iter());
1470+
14461471
// Evaluate those obligations to see if they might possibly hold.
14471472
for o in candidate_obligations {
14481473
let o = self.resolve_vars_if_possible(o);
@@ -1527,9 +1552,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15271552
}
15281553

15291554
if let ProbeResult::Match = result {
1530-
if let (Some(return_ty), Some(xform_ret_ty)) =
1531-
(self.return_type, probe.xform_ret_ty)
1532-
{
1555+
if let (Some(return_ty), Some(xform_ret_ty)) = (self.return_type, xform_ret_ty) {
15331556
let xform_ret_ty = self.resolve_vars_if_possible(xform_ret_ty);
15341557
debug!(
15351558
"comparing return_ty {:?} with xform ret ty {:?}",
@@ -1669,6 +1692,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16691692
self.static_candidates.push(source);
16701693
}
16711694

1695+
#[instrument(level = "debug", skip(self))]
16721696
fn xform_self_ty(
16731697
&self,
16741698
item: &ty::AssocItem,
@@ -1683,9 +1707,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16831707
}
16841708
}
16851709

1710+
#[instrument(level = "debug", skip(self))]
16861711
fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> {
16871712
let fn_sig = self.tcx.fn_sig(method);
1688-
debug!("xform_self_ty(fn_sig={:?}, substs={:?})", fn_sig, substs);
1713+
debug!(?fn_sig);
16891714

16901715
assert!(!substs.has_escaping_bound_vars());
16911716

0 commit comments

Comments
 (0)