about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs67
-rw-r--r--src/test/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr7
-rw-r--r--src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr7
3 files changed, 42 insertions, 39 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 47c072831e3..02b4d5bb2fb 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1523,29 +1523,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             };
 
             let mut result = ProbeResult::Match;
-            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;
-                    }
-                }
+            let mut xform_ret_ty = probe.xform_ret_ty;
+            debug!(?xform_ret_ty);
 
-                Some(normalized_xform_ret_ty)
-            } else {
-                None
-            };
+            let cause = traits::ObligationCause::misc(self.span, self.body_id);
 
             let mut parent_pred = None;
 
@@ -1555,6 +1536,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             // 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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
                     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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
             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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     .sup(return_ty, xform_ret_ty)
                     .is_err()
                 {
-                    return ProbeResult::BadReturnType;
+                    result = ProbeResult::BadReturnType;
                 }
             }
 
diff --git a/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr b/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
index 7cd9788a7d3..543ceac8e91 100644
--- a/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
+++ b/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
@@ -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> {
diff --git a/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr b/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
index 96345df73b4..f08d685836e 100644
--- a/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
+++ b/src/test/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
@@ -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> {