about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-02-17 23:51:18 +0100
committerGitHub <noreply@github.com>2021-02-17 23:51:18 +0100
commitcdd93fd3e2f6fb03717db137196a371f6b5c55f7 (patch)
treed444cd5b34cafeb6c60bd8addf309ac33ca51255
parentf79be2c6de6a2f1b002d3f1f3fd7d9ca2aa8905a (diff)
parentf852160a99721f89a6bc206bae337291c485069e (diff)
downloadrust-cdd93fd3e2f6fb03717db137196a371f6b5c55f7.tar.gz
rust-cdd93fd3e2f6fb03717db137196a371f6b5c55f7.zip
Rollup merge of #81972 - matthewjasper:hrtb-error-cleanup, r=nikomatsakis
Placeholder lifetime error cleanup

- Remove note of trait definition
- Avoid repeating the same self type
- Use original region names when possible
- Use this error kind more often
- Print closure signatures when they are suppose to implement `Fn*` traits

Works towards #57374

r? ```@nikomatsakis```
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs232
-rw-r--r--src/test/ui/associated-types/associated-types-eq-hr.stderr65
-rw-r--r--src/test/ui/generator/auto-trait-regions.stderr20
-rw-r--r--src/test/ui/hrtb/due-to-where-clause.stderr3
-rw-r--r--src/test/ui/hrtb/hrtb-cache-issue-54302.stderr3
-rw-r--r--src/test/ui/hrtb/hrtb-conflate-regions.stderr11
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr5
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr5
-rw-r--r--src/test/ui/hrtb/hrtb-just-for-static.stderr20
-rw-r--r--src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr38
-rw-r--r--src/test/ui/hrtb/hrtb-perfect-forwarding.rs39
-rw-r--r--src/test/ui/hrtb/hrtb-perfect-forwarding.stderr41
-rw-r--r--src/test/ui/hrtb/issue-46989.stderr3
-rw-r--r--src/test/ui/issues/issue-54302-cases.stderr36
-rw-r--r--src/test/ui/issues/issue-54302.stderr3
-rw-r--r--src/test/ui/issues/issue-55731.stderr9
-rw-r--r--src/test/ui/issues/issue-57843.nll.stderr2
-rw-r--r--src/test/ui/issues/issue-57843.rs6
-rw-r--r--src/test/ui/issues/issue-57843.stderr16
-rw-r--r--src/test/ui/lifetimes/issue-79187.rs2
-rw-r--r--src/test/ui/lifetimes/issue-79187.stderr19
-rw-r--r--src/test/ui/mismatched_types/closure-arg-type-mismatch.rs4
-rw-r--r--src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr36
-rw-r--r--src/test/ui/rfc1623.rs2
-rw-r--r--src/test/ui/rfc1623.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr39
-rw-r--r--src/test/ui/unboxed-closures/issue-30906.nll.stderr2
-rw-r--r--src/test/ui/unboxed-closures/issue-30906.rs12
-rw-r--r--src/test/ui/unboxed-closures/issue-30906.stderr16
-rw-r--r--src/test/ui/where-clauses/where-for-self-2.stderr13
34 files changed, 283 insertions, 451 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
index cc8f1816bc3..0599c78ebfd 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
@@ -43,7 +43,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
         self.infcx.tcx
     }
 
-    pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'cx>> {
+    pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'tcx>> {
         // Due to the improved diagnostics returned by the MIR borrow checker, only a subset of
         // the nice region errors are required when running under the MIR borrow checker.
         self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict())
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index e3c613b1d6a..2f622231a08 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty;
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// When given a `ConcreteFailure` for a function with parameters containing a named region and
     /// an anonymous region, emit an descriptive diagnostic error.
-    pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'a>> {
+    pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
         let (span, sub, sup) = self.regions()?;
 
         debug!(
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index e8e0326d978..4aecc2f40b8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -16,7 +16,7 @@ use std::fmt::{self, Write};
 impl NiceRegionError<'me, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
     /// an anonymous region, emit a descriptive diagnostic error.
-    pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'me>> {
+    pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
         match &self.error {
             ///////////////////////////////////////////////////////////////////////////
             // NB. The ordering of cases in this match is very
@@ -30,157 +30,153 @@ impl NiceRegionError<'me, 'tcx> {
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sub_placeholder @ ty::RePlaceholder(_),
                 _,
                 sup_placeholder @ ty::RePlaceholder(_),
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
+            )) => self.try_report_trait_placeholder_mismatch(
                 Some(self.tcx().mk_region(ty::ReVar(*vid))),
                 cause,
                 Some(sub_placeholder),
                 Some(sup_placeholder),
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sub_placeholder @ ty::RePlaceholder(_),
                 _,
                 _,
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
+            )) => self.try_report_trait_placeholder_mismatch(
                 Some(self.tcx().mk_region(ty::ReVar(*vid))),
                 cause,
                 Some(sub_placeholder),
                 None,
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 _,
                 _,
                 sup_placeholder @ ty::RePlaceholder(_),
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
+            )) => self.try_report_trait_placeholder_mismatch(
                 Some(self.tcx().mk_region(ty::ReVar(*vid))),
                 cause,
                 None,
                 Some(*sup_placeholder),
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
                 _,
                 _,
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sup_placeholder @ ty::RePlaceholder(_),
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
+            )) => self.try_report_trait_placeholder_mismatch(
                 Some(self.tcx().mk_region(ty::ReVar(*vid))),
                 cause,
                 None,
                 Some(*sup_placeholder),
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::UpperBoundUniverseConflict(
                 vid,
                 _,
                 _,
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sup_placeholder @ ty::RePlaceholder(_),
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
+            )) => self.try_report_trait_placeholder_mismatch(
                 Some(self.tcx().mk_region(ty::ReVar(*vid))),
                 cause,
                 None,
                 Some(*sup_placeholder),
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sub_region @ ty::RePlaceholder(_),
                 sup_region @ ty::RePlaceholder(_),
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
+            )) => self.try_report_trait_placeholder_mismatch(
                 None,
                 cause,
                 Some(*sub_region),
                 Some(*sup_region),
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sub_region @ ty::RePlaceholder(_),
                 sup_region,
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
-                Some(sup_region),
+            )) => self.try_report_trait_placeholder_mismatch(
+                (!sup_region.has_name()).then_some(sup_region),
                 cause,
-                Some(*sub_region),
+                Some(sub_region),
                 None,
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                values,
+            ),
 
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(box TypeTrace {
-                    cause,
-                    values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
-                }),
+                SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sub_region,
                 sup_region @ ty::RePlaceholder(_),
-            )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
-                Some(sub_region),
+            )) => self.try_report_trait_placeholder_mismatch(
+                (!sub_region.has_name()).then_some(sub_region),
                 cause,
                 None,
-                Some(*sup_region),
-                expected.def_id,
-                expected.substs,
-                found.substs,
-            )),
+                Some(sup_region),
+                values,
+            ),
 
             _ => None,
         }
     }
 
+    fn try_report_trait_placeholder_mismatch(
+        &self,
+        vid: Option<ty::Region<'tcx>>,
+        cause: &ObligationCause<'tcx>,
+        sub_placeholder: Option<ty::Region<'tcx>>,
+        sup_placeholder: Option<ty::Region<'tcx>>,
+        value_pairs: &ValuePairs<'tcx>,
+    ) -> Option<DiagnosticBuilder<'tcx>> {
+        let (expected_substs, found_substs, trait_def_id) = match value_pairs {
+            ValuePairs::TraitRefs(ExpectedFound { expected, found })
+                if expected.def_id == found.def_id =>
+            {
+                (expected.substs, found.substs, expected.def_id)
+            }
+            ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
+                if expected.def_id() == found.def_id() =>
+            {
+                // It's possible that the placeholders come from a binder
+                // outside of this value pair. Use `no_bound_vars` as a
+                // simple heuristic for that.
+                (expected.no_bound_vars()?.substs, found.no_bound_vars()?.substs, expected.def_id())
+            }
+            _ => return None,
+        };
+
+        Some(self.report_trait_placeholder_mismatch(
+            vid,
+            cause,
+            sub_placeholder,
+            sup_placeholder,
+            trait_def_id,
+            expected_substs,
+            found_substs,
+        ))
+    }
+
     // error[E0308]: implementation of `Foo` does not apply to enough lifetimes
     //   --> /home/nmatsakis/tmp/foo.rs:12:5
     //    |
@@ -190,7 +186,8 @@ impl NiceRegionError<'me, 'tcx> {
     //    = note: Due to a where-clause on the function `all`,
     //    = note: `T` must implement `...` for any two lifetimes `'1` and `'2`.
     //    = note: However, the type `T` only implements `...` for some specific lifetime `'2`.
-    fn try_report_placeholders_trait(
+    #[instrument(level = "debug", skip(self))]
+    fn report_trait_placeholder_mismatch(
         &self,
         vid: Option<ty::Region<'tcx>>,
         cause: &ObligationCause<'tcx>,
@@ -199,28 +196,13 @@ impl NiceRegionError<'me, 'tcx> {
         trait_def_id: DefId,
         expected_substs: SubstsRef<'tcx>,
         actual_substs: SubstsRef<'tcx>,
-    ) -> DiagnosticBuilder<'me> {
-        debug!(
-            "try_report_placeholders_trait(\
-             vid={:?}, \
-             sub_placeholder={:?}, \
-             sup_placeholder={:?}, \
-             trait_def_id={:?}, \
-             expected_substs={:?}, \
-             actual_substs={:?})",
-            vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs
-        );
-
+    ) -> DiagnosticBuilder<'tcx> {
         let span = cause.span(self.tcx());
         let msg = format!(
             "implementation of `{}` is not general enough",
             self.tcx().def_path_str(trait_def_id),
         );
         let mut err = self.tcx().sess.struct_span_err(span, &msg);
-        err.span_label(
-            self.tcx().def_span(trait_def_id),
-            format!("trait `{}` defined here", self.tcx().def_path_str(trait_def_id)),
-        );
 
         let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code {
             err.span_label(span, "doesn't satisfy where-clause");
@@ -285,17 +267,13 @@ impl NiceRegionError<'me, 'tcx> {
 
         let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
 
-        debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid);
-        debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid);
-        debug!("try_report_placeholders_trait: has_sub={:?}", has_sub);
-        debug!("try_report_placeholders_trait: has_sup={:?}", has_sup);
         debug!(
-            "try_report_placeholders_trait: actual_self_ty_has_vid={:?}",
-            actual_self_ty_has_vid
-        );
-        debug!(
-            "try_report_placeholders_trait: expected_self_ty_has_vid={:?}",
-            expected_self_ty_has_vid
+            ?actual_has_vid,
+            ?expected_has_vid,
+            ?has_sub,
+            ?has_sup,
+            ?actual_self_ty_has_vid,
+            ?expected_self_ty_has_vid,
         );
 
         self.explain_actual_impl_that_was_found(
@@ -388,6 +366,8 @@ impl NiceRegionError<'me, 'tcx> {
             value: trait_ref,
         };
 
+        let same_self_type = actual_trait_ref.self_ty() == expected_trait_ref.self_ty();
+
         let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
         expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
         expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
@@ -403,7 +383,42 @@ impl NiceRegionError<'me, 'tcx> {
                 }
             };
 
-            let mut note = if passive_voice {
+            let mut note = if same_self_type {
+                let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
+                self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
+
+                if self_ty.value.is_closure()
+                    && self
+                        .tcx()
+                        .fn_trait_kind_from_lang_item(expected_trait_ref.value.def_id)
+                        .is_some()
+                {
+                    let closure_sig = self_ty.map(|closure| {
+                        if let ty::Closure(_, substs) = closure.kind() {
+                            self.tcx().signature_unclosure(
+                                substs.as_closure().sig(),
+                                rustc_hir::Unsafety::Normal,
+                            )
+                        } else {
+                            bug!("type is not longer closure");
+                        }
+                    });
+
+                    format!(
+                        "{}closure with signature `{}` must implement `{}`",
+                        if leading_ellipsis { "..." } else { "" },
+                        closure_sig,
+                        expected_trait_ref.map(|tr| tr.print_only_trait_path()),
+                    )
+                } else {
+                    format!(
+                        "{}`{}` must implement `{}`",
+                        if leading_ellipsis { "..." } else { "" },
+                        self_ty,
+                        expected_trait_ref.map(|tr| tr.print_only_trait_path()),
+                    )
+                }
+            } else if passive_voice {
                 format!(
                     "{}`{}` would have to be implemented for the type `{}`",
                     if leading_ellipsis { "..." } else { "" },
@@ -449,7 +464,12 @@ impl NiceRegionError<'me, 'tcx> {
                 None => true,
             };
 
-            let mut note = if passive_voice {
+            let mut note = if same_self_type {
+                format!(
+                    "...but it actually implements `{}`",
+                    actual_trait_ref.map(|tr| tr.print_only_trait_path()),
+                )
+            } else if passive_voice {
                 format!(
                     "...but `{}` is actually implemented for the type `{}`",
                     actual_trait_ref.map(|tr| tr.print_only_trait_path()),
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr
index 127ab867355..6897b31fe46 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -31,82 +31,47 @@ LL |     bar::<IntStruct>();
 error: implementation of `TheTrait` is not general enough
   --> $DIR/associated-types-eq-hr.rs:96:5
    |
-LL | / pub trait TheTrait<T> {
-LL | |     type A;
-LL | |
-LL | |     fn get(&self, t: T) -> Self::A;
-LL | | }
-   | |_- trait `TheTrait` defined here
-...
-LL |       tuple_one::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
    |
    = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
 
 error: implementation of `TheTrait` is not general enough
   --> $DIR/associated-types-eq-hr.rs:96:5
    |
-LL | / pub trait TheTrait<T> {
-LL | |     type A;
-LL | |
-LL | |     fn get(&self, t: T) -> Self::A;
-LL | | }
-   | |_- trait `TheTrait` defined here
-...
-LL |       tuple_one::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
    |
    = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
 
 error: implementation of `TheTrait` is not general enough
   --> $DIR/associated-types-eq-hr.rs:102:5
    |
-LL | / pub trait TheTrait<T> {
-LL | |     type A;
-LL | |
-LL | |     fn get(&self, t: T) -> Self::A;
-LL | | }
-   | |_- trait `TheTrait` defined here
-...
-LL |       tuple_two::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
    |
    = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
 
 error: implementation of `TheTrait` is not general enough
   --> $DIR/associated-types-eq-hr.rs:102:5
    |
-LL | / pub trait TheTrait<T> {
-LL | |     type A;
-LL | |
-LL | |     fn get(&self, t: T) -> Self::A;
-LL | | }
-   | |_- trait `TheTrait` defined here
-...
-LL |       tuple_two::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
    |
    = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
 
 error: implementation of `TheTrait` is not general enough
   --> $DIR/associated-types-eq-hr.rs:112:5
    |
-LL | / pub trait TheTrait<T> {
-LL | |     type A;
-LL | |
-LL | |     fn get(&self, t: T) -> Self::A;
-LL | | }
-   | |_- trait `TheTrait` defined here
-...
-LL |       tuple_four::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+LL |     tuple_four::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
    |
    = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr
index 5ec462e1046..da3d3249f0e 100644
--- a/src/test/ui/generator/auto-trait-regions.stderr
+++ b/src/test/ui/generator/auto-trait-regions.stderr
@@ -1,33 +1,24 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:31:5
    |
-LL | auto trait Foo {}
-   | ----------------- trait `Foo` defined here
-...
 LL |     assert_foo(gen);
    |     ^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`...
-   = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
+   = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
+   = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:31:5
    |
-LL | auto trait Foo {}
-   | ----------------- trait `Foo` defined here
-...
 LL |     assert_foo(gen);
    |     ^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`...
-   = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
+   = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
+   = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:50:5
    |
-LL | auto trait Foo {}
-   | ----------------- trait `Foo` defined here
-...
 LL |     assert_foo(gen);
    |     ^^^^^^^^^^ implementation of `Foo` is not general enough
    |
@@ -37,9 +28,6 @@ LL |     assert_foo(gen);
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:50:5
    |
-LL | auto trait Foo {}
-   | ----------------- trait `Foo` defined here
-...
 LL |     assert_foo(gen);
    |     ^^^^^^^^^^ implementation of `Foo` is not general enough
    |
diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/hrtb/due-to-where-clause.stderr
index e4096ec059a..520938a6335 100644
--- a/src/test/ui/hrtb/due-to-where-clause.stderr
+++ b/src/test/ui/hrtb/due-to-where-clause.stderr
@@ -3,9 +3,6 @@ error: implementation of `Foo` is not general enough
    |
 LL |     test::<FooS>(&mut 42);
    |     ^^^^^^^^^^^^ implementation of `Foo` is not general enough
-...
-LL | trait Foo<'a> {}
-   | ---------------- trait `Foo` defined here
    |
    = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
    = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
index 003f3265935..f014eab8601 100644
--- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
+++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
@@ -1,9 +1,6 @@
 error: implementation of `Deserialize` is not general enough
   --> $DIR/hrtb-cache-issue-54302.rs:19:5
    |
-LL | trait Deserialize<'de> {}
-   | ------------------------- trait `Deserialize` defined here
-...
 LL |     assert_deserialize_owned::<&'static str>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
    |
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index 45573814d13..b1d4c0bf375 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,16 +1,11 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/hrtb-conflate-regions.rs:27:10
    |
-LL | / trait Foo<X> {
-LL | |     fn foo(&self, x: X) { }
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |   fn b() { want_foo2::<SomeStruct>(); }
-   |            ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL | fn b() { want_foo2::<SomeStruct>(); }
+   |          ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
index fe8209d054c..613f4dc4951 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
@@ -1,14 +1,11 @@
 error: implementation of `Trait` is not general enough
   --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
    |
-LL | trait Trait<T> {}
-   | ----------------- trait `Trait` defined here
-...
 LL |     foo::<()>();
    |     ^^^^^^^^^ implementation of `Trait` is not general enough
    |
    = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
-   = note: ...but `()` actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
+   = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
index 8bd23aa9018..b487ce3e0ff 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
@@ -1,14 +1,11 @@
 error: implementation of `Trait` is not general enough
   --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
    |
-LL | trait Trait<T> {}
-   | ----------------- trait `Trait` defined here
-...
 LL |     foo::<()>();
    |     ^^^^^^^^^ implementation of `Trait` is not general enough
    |
    = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>`
-   = note: ...but `()` actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
+   = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
index 5e3014317f5..ffc83aab4af 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr
@@ -1,27 +1,17 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/hrtb-just-for-static.rs:24:5
    |
-LL | / trait Foo<X> {
-LL | |     fn foo(&self, x: X) { }
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |       want_hrtb::<StaticInt>()
-   |       ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL |     want_hrtb::<StaticInt>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
-   = note: ...but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1`
+   = note: ...but it actually implements `Foo<&'static isize>`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/hrtb-just-for-static.rs:30:5
    |
-LL | / trait Foo<X> {
-LL | |     fn foo(&self, x: X) { }
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |       want_hrtb::<&'a u32>()
-   |       ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL |     want_hrtb::<&'a u32>()
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0`...
    = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr
index edce0e6702e..c3dd7949575 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr
@@ -1,11 +1,11 @@
 warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:22:1
+  --> $DIR/hrtb-perfect-forwarding.rs:16:1
    |
-LL | / fn no_hrtb<'b,T>(mut t: T)
-LL | |     where T : Bar<&'b isize>
+LL | / fn no_hrtb<'b, T>(mut t: T)
+LL | | where
+LL | |     T: Bar<&'b isize>,
 LL | | {
-LL | |     // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
-LL | |     // `&mut T : Bar<&'b isize>`.
+...  |
 LL | |     no_hrtb(&mut t);
    | |     --------------- recursive call site
 LL | | }
@@ -15,12 +15,12 @@ LL | | }
    = help: a `loop` may express intention better if this is on purpose
 
 warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:30:1
+  --> $DIR/hrtb-perfect-forwarding.rs:25:1
    |
 LL | / fn bar_hrtb<T>(mut t: T)
-LL | |     where T : for<'b> Bar<&'b isize>
+LL | | where
+LL | |     T: for<'b> Bar<&'b isize>,
 LL | | {
-LL | |     // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
 ...  |
 LL | |     bar_hrtb(&mut t);
    | |     ---------------- recursive call site
@@ -30,25 +30,26 @@ LL | | }
    = help: a `loop` may express intention better if this is on purpose
 
 warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:39:1
+  --> $DIR/hrtb-perfect-forwarding.rs:35:1
    |
-LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T)
-LL | |     where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
+LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
+LL | | where
+LL | |     T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
 LL | | {
-LL | |     // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
 ...  |
 LL | |     foo_hrtb_bar_not(&mut t);
    | |     ------------------------ recursive call site
 LL | |
+LL | |
 LL | | }
    | |_^ cannot return without recursing
    |
    = help: a `loop` may express intention better if this is on purpose
 
 error: lifetime may not live long enough
-  --> $DIR/hrtb-perfect-forwarding.rs:46:5
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
    |
-LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
+LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
    |                     -- lifetime `'b` defined here
 ...
 LL |     foo_hrtb_bar_not(&mut t);
@@ -57,18 +58,19 @@ LL |     foo_hrtb_bar_not(&mut t);
    = help: consider replacing `'b` with `'static`
 
 error: higher-ranked subtype error
-  --> $DIR/hrtb-perfect-forwarding.rs:46:5
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
    |
 LL |     foo_hrtb_bar_not(&mut t);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: function cannot return without recursing
-  --> $DIR/hrtb-perfect-forwarding.rs:50:1
+  --> $DIR/hrtb-perfect-forwarding.rs:48:1
    |
 LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
-LL | |     where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>
+LL | | where
+LL | |     T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
 LL | | {
-LL | |     // OK -- now we have `T : for<'b> Bar&'b isize>`.
+LL | |     // OK -- now we have `T : for<'b> Bar<&'b isize>`.
 LL | |     foo_hrtb_bar_hrtb(&mut t);
    | |     ------------------------- recursive call site
 LL | | }
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
index 0303a764c12..441a788359e 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs
@@ -2,25 +2,20 @@
 // is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
 
 trait Foo<X> {
-    fn foo(&mut self, x: X) { }
+    fn foo(&mut self, x: X) {}
 }
 
 trait Bar<X> {
-    fn bar(&mut self, x: X) { }
+    fn bar(&mut self, x: X) {}
 }
 
-impl<'a,X,F> Foo<X> for &'a mut F
-    where F : Foo<X> + Bar<X>
-{
-}
+impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {}
 
-impl<'a,X,F> Bar<X> for &'a mut F
-    where F : Bar<X>
-{
-}
+impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {}
 
-fn no_hrtb<'b,T>(mut t: T)
-    where T : Bar<&'b isize>
+fn no_hrtb<'b, T>(mut t: T)
+where
+    T: Bar<&'b isize>,
 {
     // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
     // `&mut T : Bar<&'b isize>`.
@@ -28,7 +23,8 @@ fn no_hrtb<'b,T>(mut t: T)
 }
 
 fn bar_hrtb<T>(mut t: T)
-    where T : for<'b> Bar<&'b isize>
+where
+    T: for<'b> Bar<&'b isize>,
 {
     // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
     // ensures that `&mut T : for<'b> Bar<&'b isize>`.  This is an
@@ -36,22 +32,25 @@ fn bar_hrtb<T>(mut t: T)
     bar_hrtb(&mut t);
 }
 
-fn foo_hrtb_bar_not<'b,T>(mut t: T)
-    where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
+fn foo_hrtb_bar_not<'b, T>(mut t: T)
+where
+    T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
 {
     // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
     // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
     // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
     // clause only specifies `T : Bar<&'b isize>`.
-    foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types
-                              //~| ERROR mismatched types
+    foo_hrtb_bar_not(&mut t);
+    //~^ ERROR implementation of `Bar` is not general enough
+    //~| ERROR implementation of `Bar` is not general enough
 }
 
 fn foo_hrtb_bar_hrtb<T>(mut t: T)
-    where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>
+where
+    T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
 {
-    // OK -- now we have `T : for<'b> Bar&'b isize>`.
+    // OK -- now we have `T : for<'b> Bar<&'b isize>`.
     foo_hrtb_bar_hrtb(&mut t);
 }
 
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
index ed810d443be..07ff9b96e44 100644
--- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr
@@ -1,41 +1,20 @@
-error[E0308]: mismatched types
-  --> $DIR/hrtb-perfect-forwarding.rs:46:5
+error: implementation of `Bar` is not general enough
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
    |
 LL |     foo_hrtb_bar_not(&mut t);
-   |     ^^^^^^^^^^^^^^^^ lifetime mismatch
+   |     ^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
    |
-   = note: expected type `Bar<&'a isize>`
-              found type `Bar<&'b isize>`
-note: the required lifetime does not necessarily outlive the lifetime `'b` as defined on the function body at 39:21
-  --> $DIR/hrtb-perfect-forwarding.rs:39:21
-   |
-LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
-   |                     ^^
-note: the lifetime requirement is introduced here
-  --> $DIR/hrtb-perfect-forwarding.rs:40:15
-   |
-LL |     where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
-   |               ^^^^^^^^^^^^^^^^^^^^^^
+   = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Bar<&'b isize>`
 
-error[E0308]: mismatched types
-  --> $DIR/hrtb-perfect-forwarding.rs:46:5
+error: implementation of `Bar` is not general enough
+  --> $DIR/hrtb-perfect-forwarding.rs:43:5
    |
 LL |     foo_hrtb_bar_not(&mut t);
-   |     ^^^^^^^^^^^^^^^^ lifetime mismatch
-   |
-   = note: expected type `Bar<&'a isize>`
-              found type `Bar<&'b isize>`
-note: the lifetime `'b` as defined on the function body at 39:21 doesn't meet the lifetime requirements
-  --> $DIR/hrtb-perfect-forwarding.rs:39:21
-   |
-LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
-   |                     ^^
-note: the lifetime requirement is introduced here
-  --> $DIR/hrtb-perfect-forwarding.rs:40:15
+   |     ^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
    |
-LL |     where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
-   |               ^^^^^^^^^^^^^^^^^^^^^^
+   = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Bar<&'b isize>`
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr
index c85c37ff923..f3d906cae4c 100644
--- a/src/test/ui/hrtb/issue-46989.stderr
+++ b/src/test/ui/hrtb/issue-46989.stderr
@@ -1,9 +1,6 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-46989.rs:38:5
    |
-LL | trait Foo {}
-   | ------------ trait `Foo` defined here
-...
 LL |     assert_foo::<fn(&i32)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
diff --git a/src/test/ui/issues/issue-54302-cases.stderr b/src/test/ui/issues/issue-54302-cases.stderr
index 3ed27791643..baa75f28d37 100644
--- a/src/test/ui/issues/issue-54302-cases.stderr
+++ b/src/test/ui/issues/issue-54302-cases.stderr
@@ -1,13 +1,8 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:63:5
    |
-LL | / trait Foo<'x, T> {
-LL | |     fn foo(self) -> &'x T;
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |       <u32 as RefFoo<u32>>::ref_foo(a)
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL |     <u32 as RefFoo<u32>>::ref_foo(a)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
    = note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
@@ -15,13 +10,8 @@ LL |       <u32 as RefFoo<u32>>::ref_foo(a)
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:69:5
    |
-LL | / trait Foo<'x, T> {
-LL | |     fn foo(self) -> &'x T;
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |       <i32 as RefFoo<i32>>::ref_foo(a)
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL |     <i32 as RefFoo<i32>>::ref_foo(a)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`...
    = note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1`
@@ -29,13 +19,8 @@ LL |       <i32 as RefFoo<i32>>::ref_foo(a)
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:75:5
    |
-LL | / trait Foo<'x, T> {
-LL | |     fn foo(self) -> &'x T;
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |       <u64 as RefFoo<u64>>::ref_foo(a)
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL |     <u64 as RefFoo<u64>>::ref_foo(a)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`...
    = note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1`
@@ -43,13 +28,8 @@ LL |       <u64 as RefFoo<u64>>::ref_foo(a)
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:81:5
    |
-LL | / trait Foo<'x, T> {
-LL | |     fn foo(self) -> &'x T;
-LL | | }
-   | |_- trait `Foo` defined here
-...
-LL |       <i64 as RefFoo<i64>>::ref_foo(a)
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+LL |     <i64 as RefFoo<i64>>::ref_foo(a)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`...
    = note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1`
diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr
index 1b3f57ba188..26c46571f9c 100644
--- a/src/test/ui/issues/issue-54302.stderr
+++ b/src/test/ui/issues/issue-54302.stderr
@@ -1,9 +1,6 @@
 error: implementation of `Deserialize` is not general enough
   --> $DIR/issue-54302.rs:13:5
    |
-LL | trait Deserialize<'de> {}
-   | ------------------------- trait `Deserialize` defined here
-...
 LL |     assert_deserialize_owned::<&'static str>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
    |
diff --git a/src/test/ui/issues/issue-55731.stderr b/src/test/ui/issues/issue-55731.stderr
index f44c842187c..de327cd3cc2 100644
--- a/src/test/ui/issues/issue-55731.stderr
+++ b/src/test/ui/issues/issue-55731.stderr
@@ -1,13 +1,8 @@
 error: implementation of `DistributedIteratorMulti` is not general enough
   --> $DIR/issue-55731.rs:48:5
    |
-LL | / trait DistributedIteratorMulti<Source> {
-LL | |     type Item;
-LL | | }
-   | |_- trait `DistributedIteratorMulti` defined here
-...
-LL |       multi(Map {
-   |       ^^^^^ implementation of `DistributedIteratorMulti` is not general enough
+LL |     multi(Map {
+   |     ^^^^^ implementation of `DistributedIteratorMulti` is not general enough
    |
    = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`...
    = note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1`
diff --git a/src/test/ui/issues/issue-57843.nll.stderr b/src/test/ui/issues/issue-57843.nll.stderr
index 70310780b43..70d16cc9a1d 100644
--- a/src/test/ui/issues/issue-57843.nll.stderr
+++ b/src/test/ui/issues/issue-57843.nll.stderr
@@ -1,5 +1,5 @@
 error: higher-ranked subtype error
-  --> $DIR/issue-57843.rs:23:9
+  --> $DIR/issue-57843.rs:25:9
    |
 LL |     Foo(Box::new(|_| ()));
    |         ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-57843.rs b/src/test/ui/issues/issue-57843.rs
index 46608255266..11629690ecc 100644
--- a/src/test/ui/issues/issue-57843.rs
+++ b/src/test/ui/issues/issue-57843.rs
@@ -11,7 +11,9 @@ trait ClonableFn<T> {
 }
 
 impl<T, F: 'static> ClonableFn<T> for F
-where F: Fn(T) + Clone {
+where
+    F: Fn(T) + Clone,
+{
     fn clone(&self) -> Box<dyn Fn(T)> {
         Box::new(self.clone())
     }
@@ -20,5 +22,5 @@ where F: Fn(T) + Clone {
 struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>);
 
 fn main() {
-    Foo(Box::new(|_| ())); //~ ERROR mismatched types
+    Foo(Box::new(|_| ())); //~ ERROR implementation of `FnOnce` is not general enough
 }
diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr
index 7699e97da99..2ab49ec61cf 100644
--- a/src/test/ui/issues/issue-57843.stderr
+++ b/src/test/ui/issues/issue-57843.stderr
@@ -1,17 +1,11 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-57843.rs:23:9
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/issue-57843.rs:25:9
    |
 LL |     Foo(Box::new(|_| ()));
-   |         ^^^^^^^^^^^^^^^^ one type is more general than the other
+   |         ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&'a bool,)>`
-              found type `FnOnce<(&bool,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57843.rs:23:18
-   |
-LL |     Foo(Box::new(|_| ()));
-   |                  ^^^^^^
+   = note: closure with signature `fn(&'2 bool)` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 bool,)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/lifetimes/issue-79187.rs b/src/test/ui/lifetimes/issue-79187.rs
index bf331d8a606..2ee69ee2234 100644
--- a/src/test/ui/lifetimes/issue-79187.rs
+++ b/src/test/ui/lifetimes/issue-79187.rs
@@ -2,5 +2,5 @@ fn thing(x: impl FnOnce(&u32)) {}
 
 fn main() {
     let f = |_| ();
-    thing(f); //~ERROR mismatched types
+    thing(f); //~ERROR implementation of `FnOnce` is not general enough
 }
diff --git a/src/test/ui/lifetimes/issue-79187.stderr b/src/test/ui/lifetimes/issue-79187.stderr
index 63f501e08fc..3c0439fb660 100644
--- a/src/test/ui/lifetimes/issue-79187.stderr
+++ b/src/test/ui/lifetimes/issue-79187.stderr
@@ -1,22 +1,11 @@
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/issue-79187.rs:5:5
    |
 LL |     thing(f);
-   |     ^^^^^ lifetime mismatch
+   |     ^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&u32,)>`
-              found type `FnOnce<(&u32,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-79187.rs:4:13
-   |
-LL |     let f = |_| ();
-   |             ^^^^^^
-note: the lifetime requirement is introduced here
-  --> $DIR/issue-79187.rs:1:18
-   |
-LL | fn thing(x: impl FnOnce(&u32)) {}
-   |                  ^^^^^^^^^^^^
+   = note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
index e278049c8cc..2d485d14a8d 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
@@ -8,8 +8,8 @@ fn main() {
 fn baz<F: Fn(*mut &u32)>(_: F) {}
 fn _test<'a>(f: fn(*mut &'a u32)) {
     baz(f);
-    //~^ ERROR mismatched types
-    //~| ERROR mismatched types
+    //~^ ERROR implementation of `FnOnce` is not general enough
+    //~| ERROR implementation of `FnOnce` is not general enough
     //~| ERROR mismatched types
     //~| ERROR mismatched types
 }
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index 02ba60f7f4b..521de3742b0 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -41,24 +41,14 @@ note: the lifetime requirement is introduced here
 LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
    |           ^^^^^^^^^^^^^
 
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
 LL |     baz(f);
-   |     ^^^ lifetime mismatch
-   |
-   = note: expected type `FnOnce<(*mut &u32,)>`
-              found type `FnOnce<(*mut &'a u32,)>`
-note: the required lifetime does not necessarily outlive the lifetime `'a` as defined on the function body at 9:10
-  --> $DIR/closure-arg-type-mismatch.rs:9:10
-   |
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-   |          ^^
-note: the lifetime requirement is introduced here
-  --> $DIR/closure-arg-type-mismatch.rs:8:11
+   |     ^^^ implementation of `FnOnce` is not general enough
    |
-LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   |           ^^^^^^^^^^^^^
+   = note: `fn(*mut &'a u32)` must implement `FnOnce<(*mut &'0 u32,)>`, for any lifetime `'0`...
+   = note: ...but it actually implements `FnOnce<(*mut &'a u32,)>`
 
 error[E0308]: mismatched types
   --> $DIR/closure-arg-type-mismatch.rs:10:5
@@ -79,24 +69,14 @@ note: the lifetime requirement is introduced here
 LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
    |           ^^^^^^^^^^^^^
 
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
 LL |     baz(f);
-   |     ^^^ lifetime mismatch
-   |
-   = note: expected type `FnOnce<(*mut &u32,)>`
-              found type `FnOnce<(*mut &'a u32,)>`
-note: the lifetime `'a` as defined on the function body at 9:10 doesn't meet the lifetime requirements
-  --> $DIR/closure-arg-type-mismatch.rs:9:10
-   |
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-   |          ^^
-note: the lifetime requirement is introduced here
-  --> $DIR/closure-arg-type-mismatch.rs:8:11
+   |     ^^^ implementation of `FnOnce` is not general enough
    |
-LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   |           ^^^^^^^^^^^^^
+   = note: `fn(*mut &'a u32)` must implement `FnOnce<(*mut &'0 u32,)>`, for any lifetime `'0`...
+   = note: ...but it actually implements `FnOnce<(*mut &'a u32,)>`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfc1623.rs
index aa6b1c0012c..9ff4813d112 100644
--- a/src/test/ui/rfc1623.rs
+++ b/src/test/ui/rfc1623.rs
@@ -22,7 +22,7 @@ static SOME_STRUCT: &SomeStruct = &SomeStruct {
     foo: &Foo { bools: &[false, true] },
     bar: &Bar { bools: &[true, true] },
     f: &id,
-    //~^ ERROR mismatched types
+    //~^ ERROR implementation of `FnOnce` is not general enough
 };
 
 // very simple test for a 'static static with default lifetime
diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr
index 2835e47fa45..e95e68c8e6d 100644
--- a/src/test/ui/rfc1623.stderr
+++ b/src/test/ui/rfc1623.stderr
@@ -1,12 +1,11 @@
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/rfc1623.rs:24:8
    |
 LL |     f: &id,
-   |        ^^^ one type is more general than the other
+   |        ^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&'a Foo<'b>,)>`
-              found type `FnOnce<(&Foo<'_>,)>`
+   = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr
index be1dd1a8524..998e178966a 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr
@@ -24,19 +24,14 @@ note: this closure does not fulfill the lifetime requirements
 LL |         |x| x
    |         ^^^^^
 
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/issue-57611-trait-alias.rs:17:16
    |
 LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&X,)>`
-              found type `FnOnce<(&'static X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:25:9
-   |
-LL |         |x| x
-   |         ^^^^^
+   = note: closure with signature `fn(&'static X) -> &'static X` must implement `FnOnce<(&'0 X,)>`, for any lifetime `'0`...
+   = note: ...but it actually implements `FnOnce<(&'static X,)>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
index 3372b81404e..561528c2abb 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -15,9 +15,9 @@ struct X;
 
 impl Foo for X {
     type Bar = impl Baz<Self, Self>;
-    //~^ ERROR mismatched types
-    //~| ERROR mismatched types
-    //~| ERROR mismatched types
+    //~^ ERROR implementation of `FnOnce` is not general enough
+    //~| ERROR implementation of `FnOnce` is not general enough
+    //~| ERROR implementation of `FnOnce` is not general enough
     //~| ERROR mismatched types
     //~| ERROR mismatched types
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
index 9d9293e958e..91c9d459ad8 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
@@ -1,16 +1,11 @@
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/issue-57611-trait-alias.rs:17:16
    |
 LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `FnOnce<(&X,)>`
-              found type `FnOnce<(&X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:25:9
+   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-LL |         |x| x
-   |         ^^^^^
+   = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error[E0308]: mismatched types
   --> $DIR/issue-57611-trait-alias.rs:17:16
@@ -26,19 +21,14 @@ note: this closure does not fulfill the lifetime requirements
 LL |         |x| x
    |         ^^^^^
 
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/issue-57611-trait-alias.rs:17:16
    |
 LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&X,)>`
-              found type `FnOnce<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:25:9
-   |
-LL |         |x| x
-   |         ^^^^^
+   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error[E0308]: mismatched types
   --> $DIR/issue-57611-trait-alias.rs:17:16
@@ -54,19 +44,14 @@ note: this closure does not fulfill the lifetime requirements
 LL |         |x| x
    |         ^^^^^
 
-error[E0308]: mismatched types
+error: implementation of `FnOnce` is not general enough
   --> $DIR/issue-57611-trait-alias.rs:17:16
    |
 LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&X,)>`
-              found type `FnOnce<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:25:9
-   |
-LL |         |x| x
-   |         ^^^^^
+   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/unboxed-closures/issue-30906.nll.stderr b/src/test/ui/unboxed-closures/issue-30906.nll.stderr
index 5a2cbab9a15..2db392e8b8b 100644
--- a/src/test/ui/unboxed-closures/issue-30906.nll.stderr
+++ b/src/test/ui/unboxed-closures/issue-30906.nll.stderr
@@ -1,5 +1,5 @@
 error: higher-ranked subtype error
-  --> $DIR/issue-30906.rs:15:5
+  --> $DIR/issue-30906.rs:18:5
    |
 LL |     test(Compose(f, |_| {}));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/unboxed-closures/issue-30906.rs b/src/test/ui/unboxed-closures/issue-30906.rs
index 03cce832775..e2d219e4703 100644
--- a/src/test/ui/unboxed-closures/issue-30906.rs
+++ b/src/test/ui/unboxed-closures/issue-30906.rs
@@ -2,9 +2,12 @@
 
 fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}
 
-struct Compose<F,G>(F,G);
-impl<T,F,G> FnOnce<(T,)> for Compose<F,G>
-where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> {
+struct Compose<F, G>(F, G);
+impl<T, F, G> FnOnce<(T,)> for Compose<F, G>
+where
+    F: FnOnce<(T,)>,
+    G: FnOnce<(F::Output,)>,
+{
     type Output = G::Output;
     extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output {
         (self.1)((self.0)(x))
@@ -12,7 +15,8 @@ where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> {
 }
 
 fn bad<T>(f: fn(&'static str) -> T) {
-    test(Compose(f, |_| {})); //~ ERROR: mismatched types
+    test(Compose(f, |_| {}));
+    //~^ ERROR: implementation of `FnOnce` is not general enough
 }
 
 fn main() {}
diff --git a/src/test/ui/unboxed-closures/issue-30906.stderr b/src/test/ui/unboxed-closures/issue-30906.stderr
index ecf3a96b5a8..35b1e454c02 100644
--- a/src/test/ui/unboxed-closures/issue-30906.stderr
+++ b/src/test/ui/unboxed-closures/issue-30906.stderr
@@ -1,17 +1,11 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-30906.rs:15:5
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/issue-30906.rs:18:5
    |
 LL |     test(Compose(f, |_| {}));
-   |     ^^^^ lifetime mismatch
+   |     ^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: expected type `FnOnce<(&'x str,)>`
-              found type `FnOnce<(&str,)>`
-note: the lifetime requirement is introduced here
-  --> $DIR/issue-30906.rs:3:12
-   |
-LL | fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `fn(&'2 str) -> T` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr
index 30eb78b2da4..6da46e20c09 100644
--- a/src/test/ui/where-clauses/where-for-self-2.stderr
+++ b/src/test/ui/where-clauses/where-for-self-2.stderr
@@ -1,16 +1,11 @@
 error: implementation of `Bar` is not general enough
   --> $DIR/where-for-self-2.rs:23:5
    |
-LL | / trait Bar {
-LL | |     fn bar(&self);
-LL | | }
-   | |_- trait `Bar` defined here
-...
-LL |       foo(&X);
-   |       ^^^ implementation of `Bar` is not general enough
+LL |     foo(&X);
+   |     ^^^ implementation of `Bar` is not general enough
    |
-   = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
-   = note: ...but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
+   = note: `&'0 u32` must implement `Bar`, for any lifetime `'0`...
+   = note: ...but `Bar` is actually implemented for the type `&'static u32`
 
 error: aborting due to previous error