about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trait_selection/traits/select/candidate_assembly.rs10
-rw-r--r--src/librustc_trait_selection/traits/select/confirmation.rs9
-rw-r--r--src/librustc_trait_selection/traits/select/mod.rs29
-rw-r--r--src/test/ui/associated-types/associated-types-eq-hr.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-eq-hr.stderr87
-rw-r--r--src/test/ui/hrtb/hrtb-conflate-regions.stderr21
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs2
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr18
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs2
-rw-r--r--src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr18
-rw-r--r--src/test/ui/hrtb/hrtb-just-for-static.stderr41
-rw-r--r--src/test/ui/hrtb/issue-46989.rs8
-rw-r--r--src/test/ui/hrtb/issue-46989.stderr15
-rw-r--r--src/test/ui/issues/issue-57362-2.stderr2
-rw-r--r--src/test/ui/where-clauses/where-for-self-2.rs8
-rw-r--r--src/test/ui/where-clauses/where-for-self-2.stderr21
16 files changed, 138 insertions, 188 deletions
diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
index 9045451056b..4dab5814f7b 100644
--- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs
+++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
@@ -163,9 +163,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => return,
         }
 
-        let result = self.infcx.probe(|snapshot| {
-            self.match_projection_obligation_against_definition_bounds(obligation, snapshot)
-        });
+        let result = self
+            .infcx
+            .probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
 
         if result {
             candidates.vec.push(ProjectionCandidate);
@@ -345,8 +345,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             obligation.predicate.def_id(),
             obligation.predicate.skip_binder().trait_ref.self_ty(),
             |impl_def_id| {
-                self.infcx.probe(|snapshot| {
-                    if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) {
+                self.infcx.probe(|_| {
+                    if let Ok(_substs) = self.match_impl(impl_def_id, obligation) {
                         candidates.vec.push(ImplCandidate(impl_def_id));
                     }
                 });
diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/src/librustc_trait_selection/traits/select/confirmation.rs
index 4837acbd1de..834bf17227d 100644
--- a/src/librustc_trait_selection/traits/select/confirmation.rs
+++ b/src/librustc_trait_selection/traits/select/confirmation.rs
@@ -121,9 +121,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) {
-        self.infcx.commit_unconditionally(|snapshot| {
-            let result =
-                self.match_projection_obligation_against_definition_bounds(obligation, snapshot);
+        self.infcx.commit_unconditionally(|_| {
+            let result = self.match_projection_obligation_against_definition_bounds(obligation);
             assert!(result);
         })
     }
@@ -265,8 +264,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // First, create the substitutions by matching the impl again,
         // this time not in a probe.
-        self.infcx.commit_unconditionally(|snapshot| {
-            let substs = self.rematch_impl(impl_def_id, obligation, snapshot);
+        self.infcx.commit_unconditionally(|_| {
+            let substs = self.rematch_impl(impl_def_id, obligation);
             debug!("confirm_impl_candidate: substs={:?}", substs);
             let cause = obligation.derived_cause(ImplDerivedObligation);
             ensure_sufficient_stack(|| {
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs
index e5960e73103..cff5efbfd0f 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/src/librustc_trait_selection/traits/select/mod.rs
@@ -21,7 +21,7 @@ use super::{Normalized, ProjectionCacheKey};
 use super::{ObligationCause, PredicateObligation, TraitObligation};
 use super::{Overflow, SelectionError, Unimplemented};
 
-use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, TypeFreshener};
+use crate::infer::{InferCtxt, InferOk, TypeFreshener};
 use crate::traits::error_reporting::InferCtxtExt;
 use crate::traits::project::ProjectionCacheKeyExt;
 use rustc_ast::attr;
@@ -1268,7 +1268,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn match_projection_obligation_against_definition_bounds(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-        snapshot: &CombinedSnapshot<'_, 'tcx>,
     ) -> bool {
         let poly_trait_predicate = self.infcx().resolve_vars_if_possible(&obligation.predicate);
         let (placeholder_trait_predicate, _) =
@@ -1299,12 +1298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             if let ty::PredicateKind::Trait(bound, _) = bound.kind() {
                 let bound = bound.to_poly_trait_ref();
                 if self.infcx.probe(|_| {
-                    self.match_projection(
-                        obligation,
-                        bound,
-                        placeholder_trait_predicate.trait_ref,
-                        snapshot,
-                    )
+                    self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref)
                 }) {
                     return Some(bound);
                 }
@@ -1321,12 +1315,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             None => false,
             Some(bound) => {
                 // Repeat the successful match, if any, this time outside of a probe.
-                let result = self.match_projection(
-                    obligation,
-                    bound,
-                    placeholder_trait_predicate.trait_ref,
-                    snapshot,
-                );
+                let result =
+                    self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref);
 
                 assert!(result);
                 true
@@ -1339,14 +1329,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &TraitObligation<'tcx>,
         trait_bound: ty::PolyTraitRef<'tcx>,
         placeholder_trait_ref: ty::TraitRef<'tcx>,
-        snapshot: &CombinedSnapshot<'_, 'tcx>,
     ) -> bool {
         debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars());
         self.infcx
             .at(&obligation.cause, obligation.param_env)
             .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound)
             .is_ok()
-            && self.infcx.leak_check(false, snapshot).is_ok()
     }
 
     fn evaluate_where_clause<'o>(
@@ -1811,9 +1799,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         impl_def_id: DefId,
         obligation: &TraitObligation<'tcx>,
-        snapshot: &CombinedSnapshot<'_, 'tcx>,
     ) -> Normalized<'tcx, SubstsRef<'tcx>> {
-        match self.match_impl(impl_def_id, obligation, snapshot) {
+        match self.match_impl(impl_def_id, obligation) {
             Ok(substs) => substs,
             Err(()) => {
                 bug!(
@@ -1829,7 +1816,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         impl_def_id: DefId,
         obligation: &TraitObligation<'tcx>,
-        snapshot: &CombinedSnapshot<'_, 'tcx>,
     ) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
         let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
 
@@ -1872,11 +1858,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
         nested_obligations.extend(obligations);
 
-        if let Err(e) = self.infcx.leak_check(false, snapshot) {
-            debug!("match_impl: failed leak check due to `{}`", e);
-            return Err(());
-        }
-
         if !self.intercrate
             && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
         {
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.rs b/src/test/ui/associated-types/associated-types-eq-hr.rs
index e6afa3f71c2..70e4be5929f 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.rs
+++ b/src/test/ui/associated-types/associated-types-eq-hr.rs
@@ -7,7 +7,7 @@ pub trait TheTrait<T> {
 }
 
 struct IntStruct {
-    x: isize
+    x: isize,
 }
 
 impl<'a> TheTrait<&'a isize> for IntStruct {
@@ -19,7 +19,7 @@ impl<'a> TheTrait<&'a isize> for IntStruct {
 }
 
 struct UintStruct {
-    x: isize
+    x: isize,
 }
 
 impl<'a> TheTrait<&'a isize> for UintStruct {
@@ -30,8 +30,7 @@ impl<'a> TheTrait<&'a isize> for UintStruct {
     }
 }
 
-struct Tuple {
-}
+struct Tuple {}
 
 impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
     type A = &'a isize;
@@ -42,37 +41,43 @@ impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
 }
 
 fn foo<T>()
-    where T : for<'x> TheTrait<&'x isize, A = &'x isize>
+where
+    T: for<'x> TheTrait<&'x isize, A = &'x isize>,
 {
     // ok for IntStruct, but not UintStruct
 }
 
 fn bar<T>()
-    where T : for<'x> TheTrait<&'x isize, A = &'x usize>
+where
+    T: for<'x> TheTrait<&'x isize, A = &'x usize>,
 {
     // ok for UintStruct, but not IntStruct
 }
 
 fn tuple_one<T>()
-    where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
+where
+    T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
 {
     // not ok for tuple, two lifetimes and we pick first
 }
 
 fn tuple_two<T>()
-    where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
+where
+    T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
 {
     // not ok for tuple, two lifetimes and we pick second
 }
 
 fn tuple_three<T>()
-    where T : for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>
+where
+    T: for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>,
 {
     // ok for tuple
 }
 
 fn tuple_four<T>()
-    where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
+where
+    T: for<'x, 'y> TheTrait<(&'x isize, &'y isize)>,
 {
     // not ok for tuple, two lifetimes, and lifetime matching is invariant
 }
@@ -89,14 +94,12 @@ pub fn call_bar() {
 
 pub fn call_tuple_one() {
     tuple_one::<Tuple>();
-    //~^ ERROR not satisfied
-    //~| ERROR type mismatch
+    //~^ ERROR type mismatch
 }
 
 pub fn call_tuple_two() {
     tuple_two::<Tuple>();
-    //~^ ERROR not satisfied
-    //~| ERROR type mismatch
+    //~^ ERROR type mismatch
 }
 
 pub fn call_tuple_three() {
@@ -105,7 +108,7 @@ pub fn call_tuple_three() {
 
 pub fn call_tuple_four() {
     tuple_four::<Tuple>();
-    //~^ ERROR not satisfied
+    //~^ ERROR implementation of `TheTrait` is not general enough
 }
 
-fn main() { }
+fn main() {}
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 315d180844d..626cb55588f 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -1,10 +1,11 @@
 error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
-  --> $DIR/associated-types-eq-hr.rs:82:5
+  --> $DIR/associated-types-eq-hr.rs:87:5
    |
 LL | fn foo<T>()
    |    --- required by a bound in this
-LL |     where T : for<'x> TheTrait<&'x isize, A = &'x isize>
-   |                                           ------------- required by this bound in `foo`
+LL | where
+LL |     T: for<'x> TheTrait<&'x isize, A = &'x isize>,
+   |                                    ------------- required by this bound in `foo`
 ...
 LL |     foo::<UintStruct>();
    |     ^^^^^^^^^^^^^^^^^ expected `isize`, found `usize`
@@ -13,12 +14,13 @@ LL |     foo::<UintStruct>();
               found reference `&usize`
 
 error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
-  --> $DIR/associated-types-eq-hr.rs:86:5
+  --> $DIR/associated-types-eq-hr.rs:91:5
    |
 LL | fn bar<T>()
    |    --- required by a bound in this
-LL |     where T : for<'x> TheTrait<&'x isize, A = &'x usize>
-   |                                           ------------- required by this bound in `bar`
+LL | where
+LL |     T: for<'x> TheTrait<&'x isize, A = &'x usize>,
+   |                                    ------------- required by this bound in `bar`
 ...
 LL |     bar::<IntStruct>();
    |     ^^^^^^^^^^^^^^^^ expected `usize`, found `isize`
@@ -26,71 +28,46 @@ LL |     bar::<IntStruct>();
    = note: expected reference `&usize`
               found reference `&isize`
 
-error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
-  --> $DIR/associated-types-eq-hr.rs:91:17
-   |
-LL | fn tuple_one<T>()
-   |    --------- required by a bound in this
-LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
-   |               ---------------------------------------------------------- required by this bound in `tuple_one`
-...
-LL |     tuple_one::<Tuple>();
-   |                 ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
-   |
-   = help: the following implementations were found:
-             <Tuple as TheTrait<(&'a isize, &'a isize)>>
-
 error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'x isize`
-  --> $DIR/associated-types-eq-hr.rs:91:5
+  --> $DIR/associated-types-eq-hr.rs:96:5
    |
 LL | fn tuple_one<T>()
    |    --------- required by a bound in this
-LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
-   |                                                           ------------- required by this bound in `tuple_one`
+LL | where
+LL |     T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
+   |                                                     ------------- required by this bound in `tuple_one`
 ...
 LL |     tuple_one::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
-
-error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
-  --> $DIR/associated-types-eq-hr.rs:97:17
-   |
-LL | fn tuple_two<T>()
-   |    --------- required by a bound in this
-LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
-   |               ---------------------------------------------------------- required by this bound in `tuple_two`
-...
-LL |     tuple_two::<Tuple>();
-   |                 ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
-   |
-   = help: the following implementations were found:
-             <Tuple as TheTrait<(&'a isize, &'a isize)>>
+   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'y isize`
-  --> $DIR/associated-types-eq-hr.rs:97:5
+  --> $DIR/associated-types-eq-hr.rs:101:5
    |
 LL | fn tuple_two<T>()
    |    --------- required by a bound in this
-LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
-   |                                                           ------------- required by this bound in `tuple_two`
+LL | where
+LL |     T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
+   |                                                     ------------- required by this bound in `tuple_two`
 ...
 LL |     tuple_two::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
+   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
 
-error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
-  --> $DIR/associated-types-eq-hr.rs:107:18
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:110:5
    |
-LL | fn tuple_four<T>()
-   |    ---------- required by a bound in this
-LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
-   |               ------------------------------------------- required by this bound in `tuple_four`
+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>();
-   |                  ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+LL |       tuple_four::<Tuple>();
+   |       ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
    |
-   = help: the following implementations were found:
-             <Tuple as TheTrait<(&'a isize, &'a isize)>>
+   = 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`
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index 7250935ea29..45573814d13 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,17 +1,16 @@
-error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
-  --> $DIR/hrtb-conflate-regions.rs:27:22
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-conflate-regions.rs:27:10
    |
-LL | fn want_foo2<T>()
-   |    --------- required by a bound in this
-LL |     where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
-   |               -------------------------------------- required by this bound in `want_foo2`
+LL | / trait Foo<X> {
+LL | |     fn foo(&self, x: X) { }
+LL | | }
+   | |_- trait `Foo` defined here
 ...
-LL | fn b() { want_foo2::<SomeStruct>(); }
-   |                      ^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
+LL |   fn b() { want_foo2::<SomeStruct>(); }
+   |            ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = help: the following implementations were found:
-             <SomeStruct as Foo<(&'a isize, &'a isize)>>
+   = 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`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs
index 4c1d4d28a09..921061916fc 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs
@@ -32,5 +32,5 @@ fn main() {
     // NB. *However*, the reinstated leak-check gives an error here.
 
     foo::<()>();
-    //~^ ERROR not satisfied
+    //~^ ERROR implementation of `Trait` is not general enough
 }
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 7a7285d3d76..fe8209d054c 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
@@ -1,18 +1,14 @@
-error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied
-  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:11
+error: implementation of `Trait` is not general enough
+  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
    |
-LL | fn foo<T>()
-   |    --- required by a bound in this
-LL | where
-LL |     T: Trait<for<'b> fn(&'b u32)>,
-   |        -------------------------- required by this bound in `foo`
+LL | trait Trait<T> {}
+   | ----------------- trait `Trait` defined here
 ...
 LL |     foo::<()>();
-   |           ^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
+   |     ^^^^^^^^^ implementation of `Trait` is not general enough
    |
-   = help: the following implementations were found:
-             <() as Trait<fn(&'a u32)>>
+   = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
+   = note: ...but `()` actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs
index 827a68beee8..b1b7ec6bcf1 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs
@@ -25,5 +25,5 @@ fn main() {
     //     yielding `fn(&!b u32)`, in a fresh universe U1
     //   - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
 
-    foo::<()>(); //~ ERROR not satisfied
+    foo::<()>(); //~ ERROR implementation of `Trait` is not general enough
 }
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 9174ea4d841..720e2276d53 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
@@ -1,18 +1,14 @@
-error[E0277]: the trait bound `(): Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not satisfied
-  --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:11
+error: implementation of `Trait` is not general enough
+  --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
    |
-LL | fn foo<T>()
-   |    --- required by a bound in this
-LL | where
-LL |     T: Trait<for<'b> fn(Cell<&'b u32>)>,
-   |        -------------------------------- required by this bound in `foo`
+LL | trait Trait<T> {}
+   | ----------------- trait `Trait` defined here
 ...
 LL |     foo::<()>();
-   |           ^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
+   |     ^^^^^^^^^ implementation of `Trait` is not general enough
    |
-   = help: the following implementations were found:
-             <() as Trait<fn(std::cell::Cell<&'a u32>)>>
+   = note: `()` must implement `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>`
+   = note: ...but `()` actually implements `Trait<fn(std::cell::Cell<&'0 u32>)>`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
index 4fa40462477..5e3014317f5 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr
@@ -1,31 +1,30 @@
-error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied
-  --> $DIR/hrtb-just-for-static.rs:24:17
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-just-for-static.rs:24:5
    |
-LL | fn want_hrtb<T>()
-   |    --------- required by a bound in this
-LL |     where T : for<'a> Foo<&'a isize>
-   |               ---------------------- required by this bound in `want_hrtb`
+LL | / trait Foo<X> {
+LL | |     fn foo(&self, x: X) { }
+LL | | }
+   | |_- trait `Foo` defined here
 ...
-LL |     want_hrtb::<StaticInt>()
-   |                 ^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
+LL |       want_hrtb::<StaticInt>()
+   |       ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = help: the following implementations were found:
-             <StaticInt as Foo<&'static isize>>
+   = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
+   = note: ...but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1`
 
-error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied
-  --> $DIR/hrtb-just-for-static.rs:30:17
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-just-for-static.rs:30:5
    |
-LL | fn want_hrtb<T>()
-   |    --------- required by a bound in this
-LL |     where T : for<'a> Foo<&'a isize>
-   |               ---------------------- required by this bound in `want_hrtb`
+LL | / trait Foo<X> {
+LL | |     fn foo(&self, x: X) { }
+LL | | }
+   | |_- trait `Foo` defined here
 ...
-LL |     want_hrtb::<&'a u32>()
-   |                 ^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
+LL |       want_hrtb::<&'a u32>()
+   |       ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = help: the following implementations were found:
-             <&'a u32 as Foo<&'a isize>>
+   = 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`
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hrtb/issue-46989.rs b/src/test/ui/hrtb/issue-46989.rs
index 2c859055458..4a09f4be156 100644
--- a/src/test/ui/hrtb/issue-46989.rs
+++ b/src/test/ui/hrtb/issue-46989.rs
@@ -28,15 +28,13 @@
 //
 // holds because 'a can be instantiated to 'empty.
 
-trait Foo {
+trait Foo {}
 
-}
-
-impl<A> Foo for fn(A) { }
+impl<A> Foo for fn(A) {}
 
 fn assert_foo<T: Foo>() {}
 
 fn main() {
     assert_foo::<fn(&i32)>();
-    //~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
+    //~^ ERROR implementation of `Foo` is not general enough
 }
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr
index 0a7382c4dd8..c85c37ff923 100644
--- a/src/test/ui/hrtb/issue-46989.stderr
+++ b/src/test/ui/hrtb/issue-46989.stderr
@@ -1,15 +1,14 @@
-error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
-  --> $DIR/issue-46989.rs:40:18
+error: implementation of `Foo` is not general enough
+  --> $DIR/issue-46989.rs:38:5
    |
-LL | fn assert_foo<T: Foo>() {}
-   |                  --- required by this bound in `assert_foo`
+LL | trait Foo {}
+   | ------------ trait `Foo` defined here
 ...
 LL |     assert_foo::<fn(&i32)>();
-   |                  ^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = help: the following implementations were found:
-             <fn(A) as Foo>
+   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
+   = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr
index 2edc0097464..47cc64ec470 100644
--- a/src/test/ui/issues/issue-57362-2.stderr
+++ b/src/test/ui/issues/issue-57362-2.stderr
@@ -4,6 +4,8 @@ error[E0599]: no function or associated item named `make_g` found for fn pointer
 LL |     let x = <fn (&())>::make_g();
    |                         ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())`
    |
+   = note: the method `make_g` exists but the following trait bounds were not satisfied:
+           `for<'r> fn(&'r ()): X`
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `X` defines an item `make_g`, perhaps you need to implement it
   --> $DIR/issue-57362-2.rs:8:1
diff --git a/src/test/ui/where-clauses/where-for-self-2.rs b/src/test/ui/where-clauses/where-for-self-2.rs
index 31174fd4cf1..37c6954fd52 100644
--- a/src/test/ui/where-clauses/where-for-self-2.rs
+++ b/src/test/ui/where-clauses/where-for-self-2.rs
@@ -14,9 +14,11 @@ impl Bar for &'static u32 {
 }
 
 fn foo<T>(x: &T)
-    where for<'a> &'a T: Bar
-{}
+where
+    for<'a> &'a T: Bar,
+{
+}
 
 fn main() {
-    foo(&X); //~ ERROR trait bound
+    foo(&X); //~ ERROR implementation of `Bar` is not general enough
 }
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 9976243b200..30eb78b2da4 100644
--- a/src/test/ui/where-clauses/where-for-self-2.stderr
+++ b/src/test/ui/where-clauses/where-for-self-2.stderr
@@ -1,17 +1,16 @@
-error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied
-  --> $DIR/where-for-self-2.rs:21:5
+error: implementation of `Bar` is not general enough
+  --> $DIR/where-for-self-2.rs:23:5
    |
-LL | fn foo<T>(x: &T)
-   |    --- required by a bound in this
-LL |     where for<'a> &'a T: Bar
-   |                          --- required by this bound in `foo`
+LL | / trait Bar {
+LL | |     fn bar(&self);
+LL | | }
+   | |_- trait `Bar` defined here
 ...
-LL |     foo(&X);
-   |     ^^^ the trait `for<'a> Bar` is not implemented for `&'a _`
+LL |       foo(&X);
+   |       ^^^ implementation of `Bar` is not general enough
    |
-   = help: the following implementations were found:
-             <&'static u32 as Bar>
+   = 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`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.