Skip to content

Commit 4f15034

Browse files
hack: don't normalize xform_ret_ty for trait/object candidates unless needed
1 parent 2600d62 commit 4f15034

File tree

3 files changed

+42
-39
lines changed

3 files changed

+42
-39
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

+42-25
Original file line numberDiff line numberDiff line change
@@ -1523,29 +1523,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15231523
};
15241524

15251525
let mut result = ProbeResult::Match;
1526-
let cause = traits::ObligationCause::misc(self.span, self.body_id);
1527-
1528-
let xform_ret_ty = if let Some(xform_ret_ty) = probe.xform_ret_ty {
1529-
// `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
1530-
// see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
1531-
// for why this is necessary
1532-
let InferOk {
1533-
value: normalized_xform_ret_ty,
1534-
obligations: normalization_obligations,
1535-
} = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
1536-
debug!("xform_ret_ty after normalization: {:?}", normalized_xform_ret_ty);
1537-
1538-
for o in normalization_obligations {
1539-
if !self.predicate_may_hold(&o) {
1540-
possibly_unsatisfied_predicates.push((o.predicate, None, Some(o.cause)));
1541-
result = ProbeResult::NoMatch;
1542-
}
1543-
}
1526+
let mut xform_ret_ty = probe.xform_ret_ty;
1527+
debug!(?xform_ret_ty);
15441528

1545-
Some(normalized_xform_ret_ty)
1546-
} else {
1547-
None
1548-
};
1529+
let cause = traits::ObligationCause::misc(self.span, self.body_id);
15491530

15501531
let mut parent_pred = None;
15511532

@@ -1555,6 +1536,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15551536
// don't have enough information to fully evaluate).
15561537
match probe.kind {
15571538
InherentImplCandidate(ref substs, ref ref_obligations) => {
1539+
// `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
1540+
// see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
1541+
// for why this is necessary
1542+
let InferOk {
1543+
value: normalized_xform_ret_ty,
1544+
obligations: normalization_obligations,
1545+
} = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
1546+
xform_ret_ty = normalized_xform_ret_ty;
1547+
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
1548+
15581549
// Check whether the impl imposes obligations we have to worry about.
15591550
let impl_def_id = probe.item.container_id(self.tcx);
15601551
let impl_bounds = self.tcx.predicates_of(impl_def_id);
@@ -1572,7 +1563,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15721563

15731564
let candidate_obligations = impl_obligations
15741565
.chain(norm_obligations.into_iter())
1575-
.chain(ref_obligations.iter().cloned());
1566+
.chain(ref_obligations.iter().cloned())
1567+
.chain(normalization_obligations.into_iter());
15761568

15771569
// Evaluate those obligations to see if they might possibly hold.
15781570
for o in candidate_obligations {
@@ -1668,8 +1660,33 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16681660

16691661
if let ProbeResult::Match = result
16701662
&& let Some(return_ty) = self.return_type
1671-
&& let Some(xform_ret_ty) = xform_ret_ty
1663+
&& let Some(mut xform_ret_ty) = xform_ret_ty
16721664
{
1665+
// `xform_ret_ty` has only been normalized for `InherentImplCandidate`.
1666+
// We don't normalize the other candidates for perf/backwards-compat reasons...
1667+
// but `self.return_type` is only set on the diagnostic-path, so we
1668+
// should be okay doing it here.
1669+
if !matches!(probe.kind, InherentImplCandidate(..)) {
1670+
let InferOk {
1671+
value: normalized_xform_ret_ty,
1672+
obligations: normalization_obligations,
1673+
} = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
1674+
xform_ret_ty = normalized_xform_ret_ty;
1675+
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
1676+
// Evaluate those obligations to see if they might possibly hold.
1677+
for o in normalization_obligations {
1678+
let o = self.resolve_vars_if_possible(o);
1679+
if !self.predicate_may_hold(&o) {
1680+
result = ProbeResult::NoMatch;
1681+
possibly_unsatisfied_predicates.push((
1682+
o.predicate,
1683+
None,
1684+
Some(o.cause),
1685+
));
1686+
}
1687+
}
1688+
}
1689+
16731690
debug!(
16741691
"comparing return_ty {:?} with xform ret ty {:?}",
16751692
return_ty, xform_ret_ty
@@ -1681,7 +1698,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16811698
.sup(return_ty, xform_ret_ty)
16821699
.is_err()
16831700
{
1684-
return ProbeResult::BadReturnType;
1701+
result = ProbeResult::BadReturnType;
16851702
}
16861703
}
16871704

src/test/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr

-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ LL | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
1717
| ^ ----------- -------------
1818
| |
1919
| unsatisfied trait bound introduced here
20-
= note: the following trait bounds were not satisfied:
21-
`&Victim<'_, Self>: VictimTrait`
22-
`&mut Victim<'_, Self>: VictimTrait`
23-
help: consider relaxing the type parameter's implicit `Sized` bound
24-
|
25-
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
26-
| ++++++++
2720
help: consider relaxing the type parameter's implicit `Sized` bound
2821
|
2922
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {

src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr

-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ LL | impl<'a, T: Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
1717
| ^ ----------- -------------
1818
| |
1919
| unsatisfied trait bound introduced here
20-
= note: the following trait bounds were not satisfied:
21-
`&Victim<'_, Self>: VictimTrait`
22-
`&mut Victim<'_, Self>: VictimTrait`
23-
help: consider relaxing the type parameter's implicit `Sized` bound
24-
|
25-
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {
26-
| ++++++++
2720
help: consider relaxing the type parameter's implicit `Sized` bound
2821
|
2922
LL | impl<'a, T: ?Sized + Perpetrator /*+ ?Sized*/> VictimTrait for Victim<'a, T> {

0 commit comments

Comments
 (0)