hack: don't normalize xform_ret_ty for trait/object candidates unless needed
This commit is contained in:
parent
2600d6245b
commit
4f15034b55
@ -1523,30 +1523,11 @@ fn consider_probe(
|
||||
};
|
||||
|
||||
let mut result = ProbeResult::Match;
|
||||
let mut xform_ret_ty = probe.xform_ret_ty;
|
||||
debug!(?xform_ret_ty);
|
||||
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
|
||||
let xform_ret_ty = if let Some(xform_ret_ty) = probe.xform_ret_ty {
|
||||
// `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
|
||||
// see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
|
||||
// for why this is necessary
|
||||
let InferOk {
|
||||
value: normalized_xform_ret_ty,
|
||||
obligations: normalization_obligations,
|
||||
} = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
|
||||
debug!("xform_ret_ty after normalization: {:?}", normalized_xform_ret_ty);
|
||||
|
||||
for o in normalization_obligations {
|
||||
if !self.predicate_may_hold(&o) {
|
||||
possibly_unsatisfied_predicates.push((o.predicate, None, Some(o.cause)));
|
||||
result = ProbeResult::NoMatch;
|
||||
}
|
||||
}
|
||||
|
||||
Some(normalized_xform_ret_ty)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut parent_pred = None;
|
||||
|
||||
// If so, impls may carry other conditions (e.g., where
|
||||
@ -1555,6 +1536,16 @@ fn consider_probe(
|
||||
// don't have enough information to fully evaluate).
|
||||
match probe.kind {
|
||||
InherentImplCandidate(ref substs, ref ref_obligations) => {
|
||||
// `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
|
||||
// see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
|
||||
// for why this is necessary
|
||||
let InferOk {
|
||||
value: normalized_xform_ret_ty,
|
||||
obligations: normalization_obligations,
|
||||
} = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
|
||||
xform_ret_ty = normalized_xform_ret_ty;
|
||||
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
|
||||
|
||||
// Check whether the impl imposes obligations we have to worry about.
|
||||
let impl_def_id = probe.item.container_id(self.tcx);
|
||||
let impl_bounds = self.tcx.predicates_of(impl_def_id);
|
||||
@ -1572,7 +1563,8 @@ fn consider_probe(
|
||||
|
||||
let candidate_obligations = impl_obligations
|
||||
.chain(norm_obligations.into_iter())
|
||||
.chain(ref_obligations.iter().cloned());
|
||||
.chain(ref_obligations.iter().cloned())
|
||||
.chain(normalization_obligations.into_iter());
|
||||
|
||||
// Evaluate those obligations to see if they might possibly hold.
|
||||
for o in candidate_obligations {
|
||||
@ -1668,8 +1660,33 @@ fn consider_probe(
|
||||
|
||||
if let ProbeResult::Match = result
|
||||
&& let Some(return_ty) = self.return_type
|
||||
&& let Some(xform_ret_ty) = xform_ret_ty
|
||||
&& let Some(mut xform_ret_ty) = xform_ret_ty
|
||||
{
|
||||
// `xform_ret_ty` has only been normalized for `InherentImplCandidate`.
|
||||
// We don't normalize the other candidates for perf/backwards-compat reasons...
|
||||
// but `self.return_type` is only set on the diagnostic-path, so we
|
||||
// should be okay doing it here.
|
||||
if !matches!(probe.kind, InherentImplCandidate(..)) {
|
||||
let InferOk {
|
||||
value: normalized_xform_ret_ty,
|
||||
obligations: normalization_obligations,
|
||||
} = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
|
||||
xform_ret_ty = normalized_xform_ret_ty;
|
||||
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
|
||||
// Evaluate those obligations to see if they might possibly hold.
|
||||
for o in normalization_obligations {
|
||||
let o = self.resolve_vars_if_possible(o);
|
||||
if !self.predicate_may_hold(&o) {
|
||||
result = ProbeResult::NoMatch;
|
||||
possibly_unsatisfied_predicates.push((
|
||||
o.predicate,
|
||||
None,
|
||||
Some(o.cause),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!(
|
||||
"comparing return_ty {:?} with xform ret ty {:?}",
|
||||
return_ty, xform_ret_ty
|
||||
@ -1681,7 +1698,7 @@ fn consider_probe(
|
||||
.sup(return_ty, xform_ret_ty)
|
||||
.is_err()
|
||||
{
|
||||
return ProbeResult::BadReturnType;
|
||||
result = ProbeResult::BadReturnType;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,6 @@ LL | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
|
||||
| ^ ----------- -------------
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`&Victim<'_, Self>: VictimTrait`
|
||||
`&mut Victim<'_, Self>: VictimTrait`
|
||||
help: consider relaxing the type parameter's implicit `Sized` bound
|
||||
|
|
||||
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
|
||||
| ++++++++
|
||||
help: consider relaxing the type parameter's implicit `Sized` bound
|
||||
|
|
||||
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
|
||||
|
@ -17,13 +17,6 @@ LL | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
|
||||
| ^ ----------- -------------
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`&Victim<'_, Self>: VictimTrait`
|
||||
`&mut Victim<'_, Self>: VictimTrait`
|
||||
help: consider relaxing the type parameter's implicit `Sized` bound
|
||||
|
|
||||
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
|
||||
| ++++++++
|
||||
help: consider relaxing the type parameter's implicit `Sized` bound
|
||||
|
|
||||
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
|
||||
|
Loading…
Reference in New Issue
Block a user