From 4e976262a1598fa48cd08fa0e429f05299d1ae3e Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Fri, 12 Aug 2022 02:00:37 +0000
Subject: [PATCH 1/4] Call them constants instead of types

---
 .../src/infer/error_reporting/mod.rs          |  5 +++
 .../generic-expr-default-concrete.stderr      |  4 +--
 ...neric-expr-default-mismatched-types.stderr |  4 +--
 .../abstract-const-as-cast-3.stderr           | 32 +++++++++----------
 .../generic_const_exprs/different-fn.stderr   |  4 +--
 .../issue-62504.full.stderr                   |  4 +--
 ...ue-72819-generic-in-const-eval.full.stderr |  8 ++---
 .../generic_const_exprs/issue-83765.stderr    |  8 ++---
 .../generic_const_exprs/issue-85848.stderr    |  4 +--
 .../const-generics/issues/issue-73260.stderr  |  8 ++---
 .../const-generics/issues/issue-79674.stderr  |  4 +--
 .../types-mismatch-const-args.full.stderr     |  4 +--
 12 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 59ea1f3f9de45..16cffb45f0f06 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1588,9 +1588,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             Mismatch::Variable(infer::ExpectedFound { expected, found }),
                         )
                     }
+                    ValuePairs::Terms(infer::ExpectedFound {
+                        expected: ty::Term::Const(_),
+                        found: ty::Term::Const(_),
+                    }) => (false, Mismatch::Fixed("constant")),
                     ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
                         (false, Mismatch::Fixed("trait"))
                     }
+                    ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
                     _ => (false, Mismatch::Fixed("type")),
                 };
                 let vals = match self.values_str(values) {
diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr
index e8826ce4335e7..61b3551182c90 100644
--- a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr
+++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     Foo::<10, 12>
    |     ^^^^^^^^^^^^^ expected `11`, found `12`
    |
-   = note: expected type `11`
-              found type `12`
+   = note: expected constant `11`
+              found constant `12`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr
index d5a3071b77d15..e83f89a60333f 100644
--- a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr
+++ b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     Foo::<N, { N + 2 }>
    |     ^^^^^^^^^^^^^^^^^^^ expected `{ N + 1 }`, found `{ N + 2 }`
    |
-   = note: expected type `{ N + 1 }`
-              found type `{ N + 2 }`
+   = note: expected constant `{ N + 1 }`
+              found constant `{ N + 2 }`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
index 615dc875f67a3..9e1297d5ee4bf 100644
--- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -22,8 +22,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
    |
-   = note: expected type `{ N as u128 }`
-              found type `{ O as u128 }`
+   = note: expected constant `{ N as u128 }`
+              found constant `{ O as u128 }`
 
 error: unconstrained generic constant
   --> $DIR/abstract-const-as-cast-3.rs:20:19
@@ -49,8 +49,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
    |
-   = note: expected type `{ N as _ }`
-              found type `{ O as u128 }`
+   = note: expected constant `{ N as _ }`
+              found constant `{ O as u128 }`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:23:5
@@ -58,8 +58,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
    |
-   = note: expected type `12`
-              found type `13`
+   = note: expected constant `12`
+              found constant `13`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:25:5
@@ -67,8 +67,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
    |
-   = note: expected type `13`
-              found type `14`
+   = note: expected constant `13`
+              found constant `14`
 
 error: unconstrained generic constant
   --> $DIR/abstract-const-as-cast-3.rs:35:19
@@ -94,8 +94,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
    |
-   = note: expected type `{ N as u128 }`
-              found type `{ O as u128 }`
+   = note: expected constant `{ N as u128 }`
+              found constant `{ O as u128 }`
 
 error: unconstrained generic constant
   --> $DIR/abstract-const-as-cast-3.rs:38:19
@@ -121,8 +121,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
    |
-   = note: expected type `{ N as _ }`
-              found type `{ O as u128 }`
+   = note: expected constant `{ N as _ }`
+              found constant `{ O as u128 }`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:41:5
@@ -130,8 +130,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
    |
-   = note: expected type `12`
-              found type `13`
+   = note: expected constant `12`
+              found constant `13`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:43:5
@@ -139,8 +139,8 @@ error[E0308]: mismatched types
 LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
    |
-   = note: expected type `13`
-              found type `14`
+   = note: expected constant `13`
+              found constant `14`
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
index 2aeb9b961ffde..83a2f3740b146 100644
--- a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     [0; size_of::<Foo<T>>()]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::<T>()`, found `size_of::<Foo<T>>()`
    |
-   = note: expected type `size_of::<T>()`
-              found type `size_of::<Foo<T>>()`
+   = note: expected constant `size_of::<T>()`
+              found constant `size_of::<Foo<T>>()`
 
 error: unconstrained generic constant
   --> $DIR/different-fn.rs:10:9
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
index f2ae361dc81d9..0742db398c9c4 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |         ArrayHolder([0; Self::SIZE])
    |                     ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
    |
-   = note: expected type `X`
-              found type `Self::SIZE`
+   = note: expected constant `X`
+              found constant `Self::SIZE`
 
 error: unconstrained generic constant
   --> $DIR/issue-62504.rs:18:25
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
index d536f6fd1d557..38dfa65e4091f 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     let x: Arr<{usize::MAX}> = Arr {};
    |            ^^^^^^^^^^^^^^^^^ expected `false`, found `true`
    |
-   = note: expected type `false`
-              found type `true`
+   = note: expected constant `false`
+              found constant `true`
 
 error[E0308]: mismatched types
   --> $DIR/issue-72819-generic-in-const-eval.rs:20:32
@@ -13,8 +13,8 @@ error[E0308]: mismatched types
 LL |     let x: Arr<{usize::MAX}> = Arr {};
    |                                ^^^ expected `false`, found `true`
    |
-   = note: expected type `false`
-              found type `true`
+   = note: expected constant `false`
+              found constant `true`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
index 0332e82fe0727..b693023f125a4 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
@@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait
 LL |     fn size(&self) -> [usize; DIM] {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
    |
-   = note: expected type `Self::DIM`
-              found type `DIM`
+   = note: expected constant `Self::DIM`
+              found constant `DIM`
 
 error: unconstrained generic constant
   --> $DIR/issue-83765.rs:32:24
@@ -26,8 +26,8 @@ error[E0308]: mismatched types
 LL |         self.reference.size()
    |         ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
    |
-   = note: expected type `DIM`
-              found type `Self::DIM`
+   = note: expected constant `DIM`
+              found constant `Self::DIM`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
index 808b305c680f3..09bcb0860b71b 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -54,8 +54,8 @@ error[E0308]: mismatched types
 LL |     writes_to_specific_path(&cap);
    |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `{ contains::<T, U>() }`
    |
-   = note: expected type `true`
-              found type `{ contains::<T, U>() }`
+   = note: expected constant `true`
+              found constant `{ contains::<T, U>() }`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/const-generics/issues/issue-73260.stderr b/src/test/ui/const-generics/issues/issue-73260.stderr
index f1fc50e6e5914..3d1f90271f9a3 100644
--- a/src/test/ui/const-generics/issues/issue-73260.stderr
+++ b/src/test/ui/const-generics/issues/issue-73260.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     let x: Arr<{usize::MAX}> = Arr {};
    |            ^^^^^^^^^^^^^^^^^ expected `false`, found `true`
    |
-   = note: expected type `false`
-              found type `true`
+   = note: expected constant `false`
+              found constant `true`
 
 error[E0308]: mismatched types
   --> $DIR/issue-73260.rs:16:32
@@ -13,8 +13,8 @@ error[E0308]: mismatched types
 LL |     let x: Arr<{usize::MAX}> = Arr {};
    |                                ^^^ expected `false`, found `true`
    |
-   = note: expected type `false`
-              found type `true`
+   = note: expected constant `false`
+              found constant `true`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/issues/issue-79674.stderr b/src/test/ui/const-generics/issues/issue-79674.stderr
index 8c029289cbb0d..344b2c5631064 100644
--- a/src/test/ui/const-generics/issues/issue-79674.stderr
+++ b/src/test/ui/const-generics/issues/issue-79674.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     requires_distinct("str", 12);
    |     ^^^^^^^^^^^^^^^^^ expected `true`, found `false`
    |
-   = note: expected type `true`
-              found type `false`
+   = note: expected constant `true`
+              found constant `false`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
index 486506239ddfd..b6a22df74369a 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
+++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData };
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4`
    |
-   = note: expected type `2`
-              found type `4`
+   = note: expected constant `2`
+              found constant `4`
 
 error[E0308]: mismatched types
   --> $DIR/types-mismatch-const-args.rs:16:41

From 4ff587263e0a7f2081e2ad5fd3e88460a94adbb5 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Fri, 12 Aug 2022 03:13:45 +0000
Subject: [PATCH 2/4] Note binding obligation causes for const equate errors

---
 compiler/rustc_middle/src/traits/mod.rs       |  7 ++++
 .../src/traits/error_reporting/mod.rs         | 19 +++++++--
 .../abstract-const-as-cast-3.stderr           | 40 +++++++++++++++++++
 ...ue-72819-generic-in-const-eval.full.stderr | 14 +++++++
 .../const-generics/issues/issue-73260.stderr  | 16 ++++++++
 .../const-generics/issues/issue-79674.stderr  |  8 ++++
 6 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 9b82320e556b3..ab7e5ba3a1067 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -469,6 +469,13 @@ impl<'tcx> ObligationCauseCode<'tcx> {
             _ => None,
         }
     }
+
+    pub fn peel_match_impls(&self) -> &Self {
+        match self {
+            MatchImpl(cause, _) => cause.code(),
+            _ => self,
+        }
+    }
 }
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 70fac83325a9c..1f031d33e0653 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1506,13 +1506,26 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 .emit();
             }
             FulfillmentErrorCode::CodeConstEquateError(ref expected_found, ref err) => {
-                self.report_mismatched_consts(
+                let mut diag = self.report_mismatched_consts(
                     &error.obligation.cause,
                     expected_found.expected,
                     expected_found.found,
                     err.clone(),
-                )
-                .emit();
+                );
+                let code = error.obligation.cause.code().peel_derives().peel_match_impls();
+                if let ObligationCauseCode::BindingObligation(..)
+                | ObligationCauseCode::ItemObligation(..) = code
+                {
+                    self.note_obligation_cause_code(
+                        &mut diag,
+                        &error.obligation.predicate,
+                        error.obligation.param_env,
+                        code,
+                        &mut vec![],
+                        &mut Default::default(),
+                    );
+                }
+                diag.emit();
             }
         }
     }
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
index 9e1297d5ee4bf..ada1050d35f35 100644
--- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -24,6 +24,11 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |
    = note: expected constant `{ N as u128 }`
               found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:14:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl::assert_impl`
 
 error: unconstrained generic constant
   --> $DIR/abstract-const-as-cast-3.rs:20:19
@@ -51,6 +56,11 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |
    = note: expected constant `{ N as _ }`
               found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:14:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl::assert_impl`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:23:5
@@ -60,6 +70,11 @@ LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
    |
    = note: expected constant `12`
               found constant `13`
+note: required by a bound in `use_trait_impl::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:14:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl::assert_impl`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:25:5
@@ -69,6 +84,11 @@ LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
    |
    = note: expected constant `13`
               found constant `14`
+note: required by a bound in `use_trait_impl::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:14:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl::assert_impl`
 
 error: unconstrained generic constant
   --> $DIR/abstract-const-as-cast-3.rs:35:19
@@ -96,6 +116,11 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |
    = note: expected constant `{ N as u128 }`
               found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:32:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
 
 error: unconstrained generic constant
   --> $DIR/abstract-const-as-cast-3.rs:38:19
@@ -123,6 +148,11 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |
    = note: expected constant `{ N as _ }`
               found constant `{ O as u128 }`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:32:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:41:5
@@ -132,6 +162,11 @@ LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
    |
    = note: expected constant `12`
               found constant `13`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:32:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:43:5
@@ -141,6 +176,11 @@ LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
    |
    = note: expected constant `13`
               found constant `14`
+note: required by a bound in `use_trait_impl_2::assert_impl`
+  --> $DIR/abstract-const-as-cast-3.rs:32:23
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
index 38dfa65e4091f..f2fddfbfbb52a 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
@@ -6,6 +6,13 @@ LL |     let x: Arr<{usize::MAX}> = Arr {};
    |
    = note: expected constant `false`
               found constant `true`
+note: required by a bound in `Arr`
+  --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
+   |
+LL | struct Arr<const N: usize>
+   |        --- required by a bound in this
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+   |                                       ^^^^^^ required by this bound in `Arr`
 
 error[E0308]: mismatched types
   --> $DIR/issue-72819-generic-in-const-eval.rs:20:32
@@ -15,6 +22,13 @@ LL |     let x: Arr<{usize::MAX}> = Arr {};
    |
    = note: expected constant `false`
               found constant `true`
+note: required by a bound in `Arr`
+  --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
+   |
+LL | struct Arr<const N: usize>
+   |        --- required by a bound in this
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+   |                                       ^^^^^^ required by this bound in `Arr`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/issues/issue-73260.stderr b/src/test/ui/const-generics/issues/issue-73260.stderr
index 3d1f90271f9a3..7670032e5b758 100644
--- a/src/test/ui/const-generics/issues/issue-73260.stderr
+++ b/src/test/ui/const-generics/issues/issue-73260.stderr
@@ -6,6 +6,14 @@ LL |     let x: Arr<{usize::MAX}> = Arr {};
    |
    = note: expected constant `false`
               found constant `true`
+note: required by a bound in `Arr`
+  --> $DIR/issue-73260.rs:6:37
+   |
+LL | struct Arr<const N: usize>
+   |        --- required by a bound in this
+LL | where
+LL |     Assert::<{N < usize::MAX / 2}>: IsTrue,
+   |                                     ^^^^^^ required by this bound in `Arr`
 
 error[E0308]: mismatched types
   --> $DIR/issue-73260.rs:16:32
@@ -15,6 +23,14 @@ LL |     let x: Arr<{usize::MAX}> = Arr {};
    |
    = note: expected constant `false`
               found constant `true`
+note: required by a bound in `Arr`
+  --> $DIR/issue-73260.rs:6:37
+   |
+LL | struct Arr<const N: usize>
+   |        --- required by a bound in this
+LL | where
+LL |     Assert::<{N < usize::MAX / 2}>: IsTrue,
+   |                                     ^^^^^^ required by this bound in `Arr`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/issues/issue-79674.stderr b/src/test/ui/const-generics/issues/issue-79674.stderr
index 344b2c5631064..02b48b55f8b38 100644
--- a/src/test/ui/const-generics/issues/issue-79674.stderr
+++ b/src/test/ui/const-generics/issues/issue-79674.stderr
@@ -6,6 +6,14 @@ LL |     requires_distinct("str", 12);
    |
    = note: expected constant `true`
               found constant `false`
+note: required by a bound in `requires_distinct`
+  --> $DIR/issue-79674.rs:23:37
+   |
+LL | fn requires_distinct<A, B>(_a: A, _b: B) where
+   |    ----------------- required by a bound in this
+LL |     A: MiniTypeId, B: MiniTypeId,
+LL |     Lift<{is_same_type::<A, B>()}>: IsFalse {}
+   |                                     ^^^^^^^ required by this bound in `requires_distinct`
 
 error: aborting due to previous error
 

From d464d3a700138b48e13d62846a35165d661e2ea4 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Fri, 12 Aug 2022 03:41:57 +0000
Subject: [PATCH 3/4] Add test for #100414

---
 .../generic_const_exprs/obligation-cause.rs   | 24 +++++++++++++++++++
 .../obligation-cause.stderr                   | 20 ++++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs
 create mode 100644 src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr

diff --git a/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs
new file mode 100644
index 0000000000000..e7c8e4f667d05
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.rs
@@ -0,0 +1,24 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait True {}
+
+struct Is<const V: bool>;
+
+impl True for Is<true> {}
+
+fn g<T>()
+//~^ NOTE required by a bound in this
+where
+    Is<{ std::mem::size_of::<T>() == 0 }>: True,
+    //~^ NOTE required by a bound in `g`
+    //~| NOTE required by this bound in `g`
+{
+}
+
+fn main() {
+    g::<usize>();
+    //~^ ERROR mismatched types
+    //~| NOTE expected `false`, found `true`
+    //~| NOTE expected constant `false`
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr
new file mode 100644
index 0000000000000..a253ec676f716
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/obligation-cause.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+  --> $DIR/obligation-cause.rs:20:5
+   |
+LL |     g::<usize>();
+   |     ^^^^^^^^^^ expected `false`, found `true`
+   |
+   = note: expected constant `false`
+              found constant `true`
+note: required by a bound in `g`
+  --> $DIR/obligation-cause.rs:13:44
+   |
+LL | fn g<T>()
+   |    - required by a bound in this
+...
+LL |     Is<{ std::mem::size_of::<T>() == 0 }>: True,
+   |                                            ^^^^ required by this bound in `g`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From 8189a4536be3730ecc161c77fc655b08be179b50 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 23 Aug 2022 05:38:18 +0000
Subject: [PATCH 4/4] Use ExprItemObligation and ExprBindingObligation too

---
 .../rustc_trait_selection/src/traits/error_reporting/mod.rs   | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 1f031d33e0653..e4af7022239b8 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1514,7 +1514,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 );
                 let code = error.obligation.cause.code().peel_derives().peel_match_impls();
                 if let ObligationCauseCode::BindingObligation(..)
-                | ObligationCauseCode::ItemObligation(..) = code
+                | ObligationCauseCode::ItemObligation(..)
+                | ObligationCauseCode::ExprBindingObligation(..)
+                | ObligationCauseCode::ExprItemObligation(..) = code
                 {
                     self.note_obligation_cause_code(
                         &mut diag,