From 5035049c798bf3f01409291577cbf87c574ff91d Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Wed, 3 Aug 2022 03:11:44 +0000
Subject: [PATCH 1/2] Emit warning when bound is trivially false

---
 compiler/rustc_typeck/src/check/wfcheck.rs    | 85 ++++++++++++++-----
 .../bound-lifetime-in-binding-only.ok.stderr  | 24 +++++-
 .../bound-lifetime-in-binding-only.rs         |  2 +
 src/test/ui/associated-types/issue-59324.rs   |  2 +-
 src/test/ui/associated-types/issue-69398.rs   |  1 +
 .../ui/associated-types/issue-69398.stderr    | 12 +++
 .../ui/consts/issue-67696-const-prop-ice.rs   |  3 +
 .../consts/issue-67696-const-prop-ice.stderr  | 20 +++++
 .../feature-gate-trivial_bounds.rs            |  1 +
 .../feature-gate-trivial_bounds.stderr        | 12 ++-
 .../normalize-under-binder/issue-89118.rs     |  2 +
 .../normalize-under-binder/issue-89118.stderr | 31 +++++--
 src/test/ui/issues/issue-36839.rs             |  1 +
 src/test/ui/issues/issue-36839.stderr         | 12 +++
 src/test/ui/issues/issue-39970.rs             |  1 +
 src/test/ui/issues/issue-39970.stderr         | 15 +++-
 src/test/ui/issues/issue-42796.rs             |  1 +
 src/test/ui/issues/issue-42796.stderr         | 14 ++-
 src/test/ui/issues/issue-50714-1.rs           |  3 +-
 src/test/ui/issues/issue-50714.rs             |  7 +-
 src/test/ui/issues/issue-50714.stderr         |  8 +-
 src/test/ui/mir/issue-91745.rs                |  1 +
 src/test/ui/mir/issue-91745.stderr            | 12 +++
 src/test/ui/trait-bounds/issue-94680.rs       |  1 +
 src/test/ui/trait-bounds/issue-94680.stderr   | 15 ++++
 src/test/ui/trait-bounds/issue-94999.rs       |  1 +
 src/test/ui/trait-bounds/issue-94999.stderr   | 15 ++++
 27 files changed, 261 insertions(+), 41 deletions(-)
 create mode 100644 src/test/ui/associated-types/issue-69398.stderr
 create mode 100644 src/test/ui/consts/issue-67696-const-prop-ice.stderr
 create mode 100644 src/test/ui/issues/issue-36839.stderr
 create mode 100644 src/test/ui/mir/issue-91745.stderr
 create mode 100644 src/test/ui/trait-bounds/issue-94680.stderr
 create mode 100644 src/test/ui/trait-bounds/issue-94999.stderr

diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 95f327112253a..d6903a890c301 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -10,7 +10,7 @@ use rustc_hir::ItemKind;
 use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
 use rustc_infer::infer::outlives::obligations::TypeOutlives;
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::Normalized;
+use rustc_infer::traits::{Normalized, TraitEngine, TraitEngineExt as _};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -27,7 +27,8 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
 use rustc_trait_selection::traits::query::normalize::AtExt;
 use rustc_trait_selection::traits::query::NoSolution;
 use rustc_trait_selection::traits::{
-    self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
+    self, FulfillmentContext, ObligationCause, ObligationCauseCode, ObligationCtxt,
+    SelectionContext, WellFormedLoc,
 };
 
 use std::cell::LazyCell;
@@ -1817,7 +1818,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
     /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
     /// aren't true.
     fn check_false_global_bounds(&mut self) {
-        let tcx = self.ocx.infcx.tcx;
+        let tcx = self.infcx.tcx;
         let mut span = self.span;
         let empty_env = ty::ParamEnv::empty();
 
@@ -1833,33 +1834,71 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
             if let ty::PredicateKind::WellFormed(..) = obligation.predicate.kind().skip_binder() {
                 continue;
             }
-            let pred = obligation.predicate;
-            // Match the existing behavior.
-            if pred.is_global() && !pred.has_late_bound_regions() {
-                let pred = self.normalize(span, None, pred);
-                let hir_node = tcx.hir().find(self.body_id);
 
-                // only use the span of the predicate clause (#90869)
+            let pred = obligation.predicate;
 
-                if let Some(hir::Generics { predicates, .. }) =
-                    hir_node.and_then(|node| node.generics())
-                {
-                    let obligation_span = obligation.cause.span();
-
-                    span = predicates
-                        .iter()
-                        // There seems to be no better way to find out which predicate we are in
-                        .find(|pred| pred.span().contains(obligation_span))
-                        .map(|pred| pred.span())
-                        .unwrap_or(obligation_span);
-                }
+            // only use the span of the predicate clause (#90869)
+            let hir_node = tcx.hir().find(self.body_id);
+            if let Some(hir::Generics { predicates, .. }) =
+                hir_node.and_then(|node| node.generics())
+            {
+                let obligation_span = obligation.cause.span();
+                span = predicates
+                    .iter()
+                    // There seems to be no better way to find out which predicate we are in
+                    .find(|pred| pred.span().contains(obligation_span))
+                    .map(|pred| pred.span())
+                    .unwrap_or(obligation_span);
+            }
 
+            // Match the existing behavior.
+            if pred.is_global() && !pred.has_late_bound_regions() {
+                let normalized_pred = self.normalize(span, None, pred);
                 let obligation = traits::Obligation::new(
                     traits::ObligationCause::new(span, self.body_id, traits::TrivialBound),
                     empty_env,
-                    pred,
+                    normalized_pred,
                 );
-                self.ocx.register_obligation(obligation);
+                self.register_obligation(obligation);
+            } else {
+                self.infcx.probe(|_| {
+                    // Manually normalize because `wfcx.normalize` may report errors
+                    let Normalized { value: normalized_pred, obligations } = traits::normalize(
+                        &mut SelectionContext::new(self.infcx),
+                        self.param_env,
+                        ObligationCause::dummy(),
+                        pred,
+                    );
+                    if normalized_pred.is_global() {
+                        let mut fulfill_cx = FulfillmentContext::new_in_snapshot();
+                        fulfill_cx.register_predicate_obligations(self.infcx, obligations);
+                        fulfill_cx.register_predicate_obligation(
+                            self.infcx,
+                            traits::Obligation::new(
+                                traits::ObligationCause::new(
+                                    span,
+                                    self.body_id,
+                                    traits::TrivialBound,
+                                ),
+                                empty_env,
+                                normalized_pred,
+                            ),
+                        );
+                        if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
+                            self.tcx()
+                                .sess
+                                .struct_span_warn(
+                                    span,
+                                    format!("the where-clause bound `{pred}` is trivially false"),
+                                )
+                                .span_label(
+                                    self.span,
+                                    "this cannot be referenced without causing an error",
+                                )
+                                .emit();
+                        }
+                    }
+                });
             }
         }
     }
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
index b709fae5a8e56..3e4d9cfed9234 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
@@ -1,8 +1,28 @@
+warning: the where-clause bound `for<'a> <Parameterized<'a> as Foo>::Item == &'a i32` is trivially false
+  --> $DIR/bound-lifetime-in-binding-only.rs:67:19
+   |
+LL |   fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
+   |  _-                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+LL | |
+LL | | }
+   | |_- this cannot be referenced without causing an error
+
+warning: the where-clause bound `for<'a> Parameterized<'a>: Foo` is trivially false
+  --> $DIR/bound-lifetime-in-binding-only.rs:67:19
+   |
+LL |   fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
+   |  _-                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+LL | |
+LL | | }
+   | |_- this cannot be referenced without causing an error
+
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/bound-lifetime-in-binding-only.rs:71:1
+  --> $DIR/bound-lifetime-in-binding-only.rs:73:1
    |
 LL | fn main() { }
    | ^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error; 2 warnings emitted
 
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs b/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs
index e714457ef7b38..e3e2daf29e073 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs
@@ -65,6 +65,8 @@ fn ok2<T: for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>>() {
 
 #[cfg(ok)]
 fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
+    //[ok]~^ WARNING the where-clause bound
+    //[ok]~| WARNING the where-clause bound
 }
 
 #[rustc_error]
diff --git a/src/test/ui/associated-types/issue-59324.rs b/src/test/ui/associated-types/issue-59324.rs
index 162f9e00edd81..87345e54d4536 100644
--- a/src/test/ui/associated-types/issue-59324.rs
+++ b/src/test/ui/associated-types/issue-59324.rs
@@ -12,7 +12,7 @@ pub trait ThriftService<Bug: NotFoo>:
 //~^ ERROR the trait bound `Bug: Foo` is not satisfied
 //~| ERROR the trait bound `Bug: Foo` is not satisfied
     Service<AssocType = <Bug as Foo>::OnlyFoo>
-{
+    {
     fn get_service(
     //~^ ERROR the trait bound `Bug: Foo` is not satisfied
         &self,
diff --git a/src/test/ui/associated-types/issue-69398.rs b/src/test/ui/associated-types/issue-69398.rs
index ca3d66b1c8eb7..01654461afea2 100644
--- a/src/test/ui/associated-types/issue-69398.rs
+++ b/src/test/ui/associated-types/issue-69398.rs
@@ -12,6 +12,7 @@ pub trait Broken {
 impl<T> Broken for T {
     type Assoc = ();
     fn broken(&self) where Self::Assoc: Foo {
+        //~^ WARNING the where-clause bound
         let _x: <Self::Assoc as Foo>::Bar;
     }
 }
diff --git a/src/test/ui/associated-types/issue-69398.stderr b/src/test/ui/associated-types/issue-69398.stderr
new file mode 100644
index 0000000000000..048b1f55e080e
--- /dev/null
+++ b/src/test/ui/associated-types/issue-69398.stderr
@@ -0,0 +1,12 @@
+warning: the where-clause bound `<T as Broken>::Assoc: Foo` is trivially false
+  --> $DIR/issue-69398.rs:14:28
+   |
+LL |       fn broken(&self) where Self::Assoc: Foo {
+   |  _____-                      ^^^^^^^^^^^^^^^^
+LL | |
+LL | |         let _x: <Self::Assoc as Foo>::Bar;
+LL | |     }
+   | |_____- this cannot be referenced without causing an error
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/consts/issue-67696-const-prop-ice.rs b/src/test/ui/consts/issue-67696-const-prop-ice.rs
index ad52608b3f46d..c04a9fd7a54ae 100644
--- a/src/test/ui/consts/issue-67696-const-prop-ice.rs
+++ b/src/test/ui/consts/issue-67696-const-prop-ice.rs
@@ -11,6 +11,9 @@ trait A {
 
 impl A for [fn(&())] {
     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
+    //~^ WARNING the where-clause bound
+    //~| WARNING the where-clause bound
+    //~| WARNING the where-clause bound
 }
 
 impl A for i32 {
diff --git a/src/test/ui/consts/issue-67696-const-prop-ice.stderr b/src/test/ui/consts/issue-67696-const-prop-ice.stderr
new file mode 100644
index 0000000000000..85e2d20389df0
--- /dev/null
+++ b/src/test/ui/consts/issue-67696-const-prop-ice.stderr
@@ -0,0 +1,20 @@
+warning: the where-clause bound `[for<'r> fn(&'r ())]: Copy` is trivially false
+  --> $DIR/issue-67696-const-prop-ice.rs:13:33
+   |
+LL |     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
+   |     ----------------------------^^^^^^^^^^------------------- this cannot be referenced without causing an error
+
+warning: the where-clause bound `[for<'r> fn(&'r ())]: Clone` is trivially false
+  --> $DIR/issue-67696-const-prop-ice.rs:13:33
+   |
+LL |     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
+   |     ----------------------------^^^^^^^^^^------------------- this cannot be referenced without causing an error
+
+warning: the where-clause bound `[for<'r> fn(&'r ())]: Sized` is trivially false
+  --> $DIR/issue-67696-const-prop-ice.rs:13:33
+   |
+LL |     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
+   |     ----------------------------^^^^^^^^^^------------------- this cannot be referenced without causing an error
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.rs b/src/test/ui/feature-gates/feature-gate-trivial_bounds.rs
index 3dbaf5dea250e..2045c87a30249 100644
--- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.rs
+++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.rs
@@ -63,6 +63,7 @@ fn return_str() -> str where str: Sized { //~ ERROR
 // This is currently accepted because the function pointer isn't
 // considered global.
 fn global_hr(x: fn(&())) where fn(&()): Foo { // OK
+    //~^ WARNING the where-clause bound
     x.test();
 }
 
diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
index 1b87ebd9f20ce..56db31e7ab64b 100644
--- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
+++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
@@ -113,6 +113,16 @@ LL | fn return_str() -> str where str: Sized {
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-error: aborting due to 11 previous errors
+warning: the where-clause bound `for<'r> fn(&'r ()): Foo` is trivially false
+  --> $DIR/feature-gate-trivial_bounds.rs:65:32
+   |
+LL |   fn global_hr(x: fn(&())) where fn(&()): Foo { // OK
+   |  _-                              ^^^^^^^^^^^^
+LL | |
+LL | |     x.test();
+LL | | }
+   | |_- this cannot be referenced without causing an error
+
+error: aborting due to 11 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs
index fffb54f86ca03..6b3a02215d95d 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs
@@ -7,6 +7,7 @@ impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
 trait StackContext
 where
     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
+    //~^ WARNING the where-clause bound
 {
     type Dispatcher;
 }
@@ -26,6 +27,7 @@ where
 struct EthernetWorker<C>(C)
 where
     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
+    //~^ WARNING the where-clause bound
 impl<C> EthernetWorker<C> {}
 //~^ ERROR: is not satisfied [E0277]
 
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
index a6858154dfb29..b1fa127c26a1d 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
@@ -1,5 +1,18 @@
+warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is trivially false
+  --> $DIR/issue-89118.rs:9:5
+   |
+LL | / trait StackContext
+LL | | where
+LL | |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
+   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+LL | | {
+LL | |     type Dispatcher;
+LL | | }
+   | |_- this cannot be referenced without causing an error
+
 error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
-  --> $DIR/issue-89118.rs:19:8
+  --> $DIR/issue-89118.rs:20:8
    |
 LL |     C: StackContext,
    |        ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
@@ -18,8 +31,16 @@ LL | where
 LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
 
+warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is trivially false
+  --> $DIR/issue-89118.rs:29:5
+   |
+LL | / struct EthernetWorker<C>(C)
+LL | | where
+LL | |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
+   | |_____^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- this cannot be referenced without causing an error
+
 error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
-  --> $DIR/issue-89118.rs:29:9
+  --> $DIR/issue-89118.rs:31:9
    |
 LL | impl<C> EthernetWorker<C> {}
    |         ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
@@ -30,7 +51,7 @@ note: required because of the requirements on the impl of `for<'a> BufferUdpStat
 LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^     ^
 note: required by a bound in `EthernetWorker`
-  --> $DIR/issue-89118.rs:28:14
+  --> $DIR/issue-89118.rs:29:14
    |
 LL | struct EthernetWorker<C>(C)
    |        -------------- required by a bound in this
@@ -39,7 +60,7 @@ LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker`
 
 error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
-  --> $DIR/issue-89118.rs:22:20
+  --> $DIR/issue-89118.rs:23:20
    |
 LL |     type Handler = Ctx<C::Dispatcher>;
    |                    ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
@@ -58,6 +79,6 @@ LL | where
 LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
 
-error: aborting due to 3 previous errors
+error: aborting due to 3 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-36839.rs b/src/test/ui/issues/issue-36839.rs
index ca3d66b1c8eb7..01654461afea2 100644
--- a/src/test/ui/issues/issue-36839.rs
+++ b/src/test/ui/issues/issue-36839.rs
@@ -12,6 +12,7 @@ pub trait Broken {
 impl<T> Broken for T {
     type Assoc = ();
     fn broken(&self) where Self::Assoc: Foo {
+        //~^ WARNING the where-clause bound
         let _x: <Self::Assoc as Foo>::Bar;
     }
 }
diff --git a/src/test/ui/issues/issue-36839.stderr b/src/test/ui/issues/issue-36839.stderr
new file mode 100644
index 0000000000000..eefa57e8dcc99
--- /dev/null
+++ b/src/test/ui/issues/issue-36839.stderr
@@ -0,0 +1,12 @@
+warning: the where-clause bound `<T as Broken>::Assoc: Foo` is trivially false
+  --> $DIR/issue-36839.rs:14:28
+   |
+LL |       fn broken(&self) where Self::Assoc: Foo {
+   |  _____-                      ^^^^^^^^^^^^^^^^
+LL | |
+LL | |         let _x: <Self::Assoc as Foo>::Bar;
+LL | |     }
+   | |_____- this cannot be referenced without causing an error
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/issues/issue-39970.rs b/src/test/ui/issues/issue-39970.rs
index f51e3b522e1c5..b3205eeac78c9 100644
--- a/src/test/ui/issues/issue-39970.rs
+++ b/src/test/ui/issues/issue-39970.rs
@@ -13,6 +13,7 @@ impl<'a> Array<'a> for () {
 impl Visit for () where
     //(): for<'a> Array<'a, Element=&'a ()>, // No ICE
     (): for<'a> Array<'a, Element=()>, // ICE
+    //~^ WARNING the where-clause bound
 {}
 
 fn main() {
diff --git a/src/test/ui/issues/issue-39970.stderr b/src/test/ui/issues/issue-39970.stderr
index 1f64a90bc1cf9..506300714f318 100644
--- a/src/test/ui/issues/issue-39970.stderr
+++ b/src/test/ui/issues/issue-39970.stderr
@@ -1,5 +1,16 @@
+warning: the where-clause bound `for<'a> <() as Array<'a>>::Element == ()` is trivially false
+  --> $DIR/issue-39970.rs:15:5
+   |
+LL | / impl Visit for () where
+LL | |     //(): for<'a> Array<'a, Element=&'a ()>, // No ICE
+LL | |     (): for<'a> Array<'a, Element=()>, // ICE
+   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+LL | | {}
+   | |__- this cannot be referenced without causing an error
+
 error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
-  --> $DIR/issue-39970.rs:19:5
+  --> $DIR/issue-39970.rs:20:5
    |
 LL |     <() as Visit>::visit();
    |     ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
@@ -15,6 +26,6 @@ note: required because of the requirements on the impl of `Visit` for `()`
 LL | impl Visit for () where
    |      ^^^^^     ^^
 
-error: aborting due to previous error
+error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/issues/issue-42796.rs b/src/test/ui/issues/issue-42796.rs
index 5e83a1cd67785..d9b723876e5ef 100644
--- a/src/test/ui/issues/issue-42796.rs
+++ b/src/test/ui/issues/issue-42796.rs
@@ -7,6 +7,7 @@ impl<T, Smoke> Mirror<Smoke> for T {
 }
 
 pub fn poison<S>(victim: String) where <String as Mirror<S>>::Image: Copy {
+    //~^ WARNING the where-clause bound
     loop { drop(victim); }
 }
 
diff --git a/src/test/ui/issues/issue-42796.stderr b/src/test/ui/issues/issue-42796.stderr
index f3e0e7b20a178..3f641929ef3cd 100644
--- a/src/test/ui/issues/issue-42796.stderr
+++ b/src/test/ui/issues/issue-42796.stderr
@@ -1,5 +1,15 @@
+warning: the where-clause bound `<String as Mirror<S>>::Image: Copy` is trivially false
+  --> $DIR/issue-42796.rs:9:40
+   |
+LL |   pub fn poison<S>(victim: String) where <String as Mirror<S>>::Image: Copy {
+   |  _-                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+LL | |     loop { drop(victim); }
+LL | | }
+   | |_- this cannot be referenced without causing an error
+
 error[E0382]: borrow of moved value: `s`
-  --> $DIR/issue-42796.rs:18:20
+  --> $DIR/issue-42796.rs:19:20
    |
 LL |     let s = "Hello!".to_owned();
    |         - move occurs because `s` has type `String`, which does not implement the `Copy` trait
@@ -11,6 +21,6 @@ LL |     println!("{}", s);
    |
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to previous error
+error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/issues/issue-50714-1.rs b/src/test/ui/issues/issue-50714-1.rs
index a25940ce1cbef..0b1c9f46f248b 100644
--- a/src/test/ui/issues/issue-50714-1.rs
+++ b/src/test/ui/issues/issue-50714-1.rs
@@ -6,6 +6,7 @@
 extern crate std;
 
 #[start]
-fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { //~ ERROR [E0647]
+fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq {
+    //~^ ERROR start function is not allowed to have a `where` clause
     0
 }
diff --git a/src/test/ui/issues/issue-50714.rs b/src/test/ui/issues/issue-50714.rs
index c571a470cee1c..32da3748fed9c 100644
--- a/src/test/ui/issues/issue-50714.rs
+++ b/src/test/ui/issues/issue-50714.rs
@@ -1,3 +1,8 @@
 // Regression test for issue 50714, make sure that this isn't a linker error.
 
-fn main() where fn(&()): Eq {} //~ ERROR [E0646]
+fn main()
+where
+//~^ ERROR `main` function is not allowed to have a `where` clause
+    fn(&()): Eq,
+{
+}
diff --git a/src/test/ui/issues/issue-50714.stderr b/src/test/ui/issues/issue-50714.stderr
index a11aceb6211c5..d02cb51523a8f 100644
--- a/src/test/ui/issues/issue-50714.stderr
+++ b/src/test/ui/issues/issue-50714.stderr
@@ -1,8 +1,10 @@
 error[E0646]: `main` function is not allowed to have a `where` clause
-  --> $DIR/issue-50714.rs:3:11
+  --> $DIR/issue-50714.rs:4:1
    |
-LL | fn main() where fn(&()): Eq {}
-   |           ^^^^^^^^^^^^^^^^^ `main` cannot have a `where` clause
+LL | / where
+LL | |
+LL | |     fn(&()): Eq,
+   | |________________^ `main` cannot have a `where` clause
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mir/issue-91745.rs b/src/test/ui/mir/issue-91745.rs
index ca3d66b1c8eb7..01654461afea2 100644
--- a/src/test/ui/mir/issue-91745.rs
+++ b/src/test/ui/mir/issue-91745.rs
@@ -12,6 +12,7 @@ pub trait Broken {
 impl<T> Broken for T {
     type Assoc = ();
     fn broken(&self) where Self::Assoc: Foo {
+        //~^ WARNING the where-clause bound
         let _x: <Self::Assoc as Foo>::Bar;
     }
 }
diff --git a/src/test/ui/mir/issue-91745.stderr b/src/test/ui/mir/issue-91745.stderr
new file mode 100644
index 0000000000000..bcb191bac9a1f
--- /dev/null
+++ b/src/test/ui/mir/issue-91745.stderr
@@ -0,0 +1,12 @@
+warning: the where-clause bound `<T as Broken>::Assoc: Foo` is trivially false
+  --> $DIR/issue-91745.rs:14:28
+   |
+LL |       fn broken(&self) where Self::Assoc: Foo {
+   |  _____-                      ^^^^^^^^^^^^^^^^
+LL | |
+LL | |         let _x: <Self::Assoc as Foo>::Bar;
+LL | |     }
+   | |_____- this cannot be referenced without causing an error
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/trait-bounds/issue-94680.rs b/src/test/ui/trait-bounds/issue-94680.rs
index 58e892079e65f..fc8463bcf9214 100644
--- a/src/test/ui/trait-bounds/issue-94680.rs
+++ b/src/test/ui/trait-bounds/issue-94680.rs
@@ -7,6 +7,7 @@ fn main() {
         pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
         where
             for<'any> &'any mut T: Clone,
+            //~^ WARNING the where-clause bound
         {
             (it.clone(), it)
         }
diff --git a/src/test/ui/trait-bounds/issue-94680.stderr b/src/test/ui/trait-bounds/issue-94680.stderr
new file mode 100644
index 0000000000000..ca0be2a70f82a
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-94680.stderr
@@ -0,0 +1,15 @@
+warning: the where-clause bound `for<'any> &'any mut (): Clone` is trivially false
+  --> $DIR/issue-94680.rs:9:13
+   |
+LL | /         pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
+LL | |         where
+LL | |             for<'any> &'any mut T: Clone,
+   | |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+LL | |         {
+LL | |             (it.clone(), it)
+LL | |         }
+   | |_________- this cannot be referenced without causing an error
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/trait-bounds/issue-94999.rs b/src/test/ui/trait-bounds/issue-94999.rs
index e131902346f1b..b2116874072b4 100644
--- a/src/test/ui/trait-bounds/issue-94999.rs
+++ b/src/test/ui/trait-bounds/issue-94999.rs
@@ -24,6 +24,7 @@ impl Holds for X {
 impl<Q> Clone for X
 where
     <S as Identity<Q>>::T: Clone,
+    //~^ WARNING the where-clause bound
     X: Holds<Q = Q>,
 {
     fn clone(&self) -> Self {
diff --git a/src/test/ui/trait-bounds/issue-94999.stderr b/src/test/ui/trait-bounds/issue-94999.stderr
new file mode 100644
index 0000000000000..04dbea8284b53
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-94999.stderr
@@ -0,0 +1,15 @@
+warning: the where-clause bound `<S as Identity<Q>>::T: Clone` is trivially false
+  --> $DIR/issue-94999.rs:26:5
+   |
+LL | / impl<Q> Clone for X
+LL | | where
+LL | |     <S as Identity<Q>>::T: Clone,
+   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | |
+...  |
+LL | |     }
+LL | | }
+   | |_- this cannot be referenced without causing an error
+
+warning: 1 warning emitted
+

From d7fbaea9d7899ce2ae18dd0c9ba465e6d5e1fa6a Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Wed, 3 Aug 2022 06:22:45 +0000
Subject: [PATCH 2/2] Adjust diagnostic

---
 compiler/rustc_typeck/src/check/wfcheck.rs    | 21 ++++++++++++-------
 .../bound-lifetime-in-binding-only.ok.stderr  | 12 +++++++----
 .../ui/associated-types/issue-69398.stderr    |  6 ++++--
 .../consts/issue-67696-const-prop-ice.stderr  | 18 ++++++++++------
 .../feature-gate-trivial_bounds.stderr        |  6 ++++--
 .../normalize-under-binder/issue-89118.stderr | 12 +++++++----
 src/test/ui/issues/issue-36839.stderr         |  6 ++++--
 src/test/ui/issues/issue-39970.stderr         |  6 ++++--
 src/test/ui/issues/issue-42796.stderr         |  6 ++++--
 src/test/ui/mir/issue-91745.stderr            |  6 ++++--
 src/test/ui/trait-bounds/issue-94680.stderr   |  6 ++++--
 src/test/ui/trait-bounds/issue-94999.stderr   |  6 ++++--
 12 files changed, 73 insertions(+), 38 deletions(-)

diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index d6903a890c301..d2dcd07a24009 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1885,17 +1885,22 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
                             ),
                         );
                         if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
-                            self.tcx()
+                            let mut diag = self.tcx()
                                 .sess
                                 .struct_span_warn(
                                     span,
-                                    format!("the where-clause bound `{pred}` is trivially false"),
-                                )
-                                .span_label(
-                                    self.span,
-                                    "this cannot be referenced without causing an error",
-                                )
-                                .emit();
+                                    format!("the where-clause bound `{pred}` is impossible to satisfy"),
+                                );
+                            diag.span_label(
+                                self.span,
+                                "this item cannot be referenced without causing an error",
+                            );
+                            if self.infcx.tcx.sess.opts.unstable_features.is_nightly_build() {
+                                diag.help(
+                                    "add `#![feature(trivial_bounds)]` to the crate attributes to allow it",
+                                );
+                            }
+                            diag.emit();
                         }
                     }
                 });
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
index 3e4d9cfed9234..06036ee3ac25d 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `for<'a> <Parameterized<'a> as Foo>::Item == &'a i32` is trivially false
+warning: the where-clause bound `for<'a> <Parameterized<'a> as Foo>::Item == &'a i32` is impossible to satisfy
   --> $DIR/bound-lifetime-in-binding-only.rs:67:19
    |
 LL |   fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
@@ -6,9 +6,11 @@ LL |   fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
 LL | |
 LL | |
 LL | | }
-   | |_- this cannot be referenced without causing an error
+   | |_- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
-warning: the where-clause bound `for<'a> Parameterized<'a>: Foo` is trivially false
+warning: the where-clause bound `for<'a> Parameterized<'a>: Foo` is impossible to satisfy
   --> $DIR/bound-lifetime-in-binding-only.rs:67:19
    |
 LL |   fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
@@ -16,7 +18,9 @@ LL |   fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
 LL | |
 LL | |
 LL | | }
-   | |_- this cannot be referenced without causing an error
+   | |_- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 error: fatal error triggered by #[rustc_error]
   --> $DIR/bound-lifetime-in-binding-only.rs:73:1
diff --git a/src/test/ui/associated-types/issue-69398.stderr b/src/test/ui/associated-types/issue-69398.stderr
index 048b1f55e080e..8bc51ea5eec12 100644
--- a/src/test/ui/associated-types/issue-69398.stderr
+++ b/src/test/ui/associated-types/issue-69398.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `<T as Broken>::Assoc: Foo` is trivially false
+warning: the where-clause bound `<T as Broken>::Assoc: Foo` is impossible to satisfy
   --> $DIR/issue-69398.rs:14:28
    |
 LL |       fn broken(&self) where Self::Assoc: Foo {
@@ -6,7 +6,9 @@ LL |       fn broken(&self) where Self::Assoc: Foo {
 LL | |
 LL | |         let _x: <Self::Assoc as Foo>::Bar;
 LL | |     }
-   | |_____- this cannot be referenced without causing an error
+   | |_____- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/consts/issue-67696-const-prop-ice.stderr b/src/test/ui/consts/issue-67696-const-prop-ice.stderr
index 85e2d20389df0..2cbd1bcde740a 100644
--- a/src/test/ui/consts/issue-67696-const-prop-ice.stderr
+++ b/src/test/ui/consts/issue-67696-const-prop-ice.stderr
@@ -1,20 +1,26 @@
-warning: the where-clause bound `[for<'r> fn(&'r ())]: Copy` is trivially false
+warning: the where-clause bound `[for<'r> fn(&'r ())]: Copy` is impossible to satisfy
   --> $DIR/issue-67696-const-prop-ice.rs:13:33
    |
 LL |     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
-   |     ----------------------------^^^^^^^^^^------------------- this cannot be referenced without causing an error
+   |     ----------------------------^^^^^^^^^^------------------- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
-warning: the where-clause bound `[for<'r> fn(&'r ())]: Clone` is trivially false
+warning: the where-clause bound `[for<'r> fn(&'r ())]: Clone` is impossible to satisfy
   --> $DIR/issue-67696-const-prop-ice.rs:13:33
    |
 LL |     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
-   |     ----------------------------^^^^^^^^^^------------------- this cannot be referenced without causing an error
+   |     ----------------------------^^^^^^^^^^------------------- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
-warning: the where-clause bound `[for<'r> fn(&'r ())]: Sized` is trivially false
+warning: the where-clause bound `[for<'r> fn(&'r ())]: Sized` is impossible to satisfy
   --> $DIR/issue-67696-const-prop-ice.rs:13:33
    |
 LL |     fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
-   |     ----------------------------^^^^^^^^^^------------------- this cannot be referenced without causing an error
+   |     ----------------------------^^^^^^^^^^------------------- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 warning: 3 warnings emitted
 
diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
index 56db31e7ab64b..4914b05260ef1 100644
--- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
+++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
@@ -113,7 +113,7 @@ LL | fn return_str() -> str where str: Sized {
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-warning: the where-clause bound `for<'r> fn(&'r ()): Foo` is trivially false
+warning: the where-clause bound `for<'r> fn(&'r ()): Foo` is impossible to satisfy
   --> $DIR/feature-gate-trivial_bounds.rs:65:32
    |
 LL |   fn global_hr(x: fn(&())) where fn(&()): Foo { // OK
@@ -121,7 +121,9 @@ LL |   fn global_hr(x: fn(&())) where fn(&()): Foo { // OK
 LL | |
 LL | |     x.test();
 LL | | }
-   | |_- this cannot be referenced without causing an error
+   | |_- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 error: aborting due to 11 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
index b1fa127c26a1d..c609a20fcb37a 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is trivially false
+warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is impossible to satisfy
   --> $DIR/issue-89118.rs:9:5
    |
 LL | / trait StackContext
@@ -9,7 +9,9 @@ LL | |
 LL | | {
 LL | |     type Dispatcher;
 LL | | }
-   | |_- this cannot be referenced without causing an error
+   | |_- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
   --> $DIR/issue-89118.rs:20:8
@@ -31,13 +33,15 @@ LL | where
 LL |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
 
-warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is trivially false
+warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is impossible to satisfy
   --> $DIR/issue-89118.rs:29:5
    |
 LL | / struct EthernetWorker<C>(C)
 LL | | where
 LL | |     Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
-   | |_____^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- this cannot be referenced without causing an error
+   | |_____^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
   --> $DIR/issue-89118.rs:31:9
diff --git a/src/test/ui/issues/issue-36839.stderr b/src/test/ui/issues/issue-36839.stderr
index eefa57e8dcc99..8dd876a690e90 100644
--- a/src/test/ui/issues/issue-36839.stderr
+++ b/src/test/ui/issues/issue-36839.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `<T as Broken>::Assoc: Foo` is trivially false
+warning: the where-clause bound `<T as Broken>::Assoc: Foo` is impossible to satisfy
   --> $DIR/issue-36839.rs:14:28
    |
 LL |       fn broken(&self) where Self::Assoc: Foo {
@@ -6,7 +6,9 @@ LL |       fn broken(&self) where Self::Assoc: Foo {
 LL | |
 LL | |         let _x: <Self::Assoc as Foo>::Bar;
 LL | |     }
-   | |_____- this cannot be referenced without causing an error
+   | |_____- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/issues/issue-39970.stderr b/src/test/ui/issues/issue-39970.stderr
index 506300714f318..514a1b1df86aa 100644
--- a/src/test/ui/issues/issue-39970.stderr
+++ b/src/test/ui/issues/issue-39970.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `for<'a> <() as Array<'a>>::Element == ()` is trivially false
+warning: the where-clause bound `for<'a> <() as Array<'a>>::Element == ()` is impossible to satisfy
   --> $DIR/issue-39970.rs:15:5
    |
 LL | / impl Visit for () where
@@ -7,7 +7,9 @@ LL | |     (): for<'a> Array<'a, Element=()>, // ICE
    | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL | |
 LL | | {}
-   | |__- this cannot be referenced without causing an error
+   | |__- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
   --> $DIR/issue-39970.rs:20:5
diff --git a/src/test/ui/issues/issue-42796.stderr b/src/test/ui/issues/issue-42796.stderr
index 3f641929ef3cd..2e3ea6bf929ad 100644
--- a/src/test/ui/issues/issue-42796.stderr
+++ b/src/test/ui/issues/issue-42796.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `<String as Mirror<S>>::Image: Copy` is trivially false
+warning: the where-clause bound `<String as Mirror<S>>::Image: Copy` is impossible to satisfy
   --> $DIR/issue-42796.rs:9:40
    |
 LL |   pub fn poison<S>(victim: String) where <String as Mirror<S>>::Image: Copy {
@@ -6,7 +6,9 @@ LL |   pub fn poison<S>(victim: String) where <String as Mirror<S>>::Image: Copy
 LL | |
 LL | |     loop { drop(victim); }
 LL | | }
-   | |_- this cannot be referenced without causing an error
+   | |_- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 error[E0382]: borrow of moved value: `s`
   --> $DIR/issue-42796.rs:19:20
diff --git a/src/test/ui/mir/issue-91745.stderr b/src/test/ui/mir/issue-91745.stderr
index bcb191bac9a1f..ae38f01dc3c80 100644
--- a/src/test/ui/mir/issue-91745.stderr
+++ b/src/test/ui/mir/issue-91745.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `<T as Broken>::Assoc: Foo` is trivially false
+warning: the where-clause bound `<T as Broken>::Assoc: Foo` is impossible to satisfy
   --> $DIR/issue-91745.rs:14:28
    |
 LL |       fn broken(&self) where Self::Assoc: Foo {
@@ -6,7 +6,9 @@ LL |       fn broken(&self) where Self::Assoc: Foo {
 LL | |
 LL | |         let _x: <Self::Assoc as Foo>::Bar;
 LL | |     }
-   | |_____- this cannot be referenced without causing an error
+   | |_____- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/trait-bounds/issue-94680.stderr b/src/test/ui/trait-bounds/issue-94680.stderr
index ca0be2a70f82a..73e14dd9dce7a 100644
--- a/src/test/ui/trait-bounds/issue-94680.stderr
+++ b/src/test/ui/trait-bounds/issue-94680.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `for<'any> &'any mut (): Clone` is trivially false
+warning: the where-clause bound `for<'any> &'any mut (): Clone` is impossible to satisfy
   --> $DIR/issue-94680.rs:9:13
    |
 LL | /         pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
@@ -9,7 +9,9 @@ LL | |
 LL | |         {
 LL | |             (it.clone(), it)
 LL | |         }
-   | |_________- this cannot be referenced without causing an error
+   | |_________- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/trait-bounds/issue-94999.stderr b/src/test/ui/trait-bounds/issue-94999.stderr
index 04dbea8284b53..91863e754b44a 100644
--- a/src/test/ui/trait-bounds/issue-94999.stderr
+++ b/src/test/ui/trait-bounds/issue-94999.stderr
@@ -1,4 +1,4 @@
-warning: the where-clause bound `<S as Identity<Q>>::T: Clone` is trivially false
+warning: the where-clause bound `<S as Identity<Q>>::T: Clone` is impossible to satisfy
   --> $DIR/issue-94999.rs:26:5
    |
 LL | / impl<Q> Clone for X
@@ -9,7 +9,9 @@ LL | |
 ...  |
 LL | |     }
 LL | | }
-   | |_- this cannot be referenced without causing an error
+   | |_- this item cannot be referenced without causing an error
+   |
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it
 
 warning: 1 warning emitted