about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs25
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs82
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs11
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr8
-rw-r--r--src/test/ui/generic-associated-types/issue-86483.stderr16
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr8
-rw-r--r--src/test/ui/issues/issue-54943.stderr6
-rw-r--r--src/test/ui/kindck/kindck-send-object1.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr7
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr7
-rw-r--r--src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr8
-rw-r--r--src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr6
-rw-r--r--src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr36
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-5.stderr8
-rw-r--r--src/test/ui/regions/regions-infer-bound-from-trait-self.stderr7
-rw-r--r--src/test/ui/regions/regions-infer-bound-from-trait.stderr16
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr8
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr8
-rw-r--r--src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed2
-rw-r--r--src/test/ui/suggestions/suggest-impl-trait-lifetime.rs2
-rw-r--r--src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr8
24 files changed, 238 insertions, 55 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index f885c0a4b87..e236ea1f893 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -89,16 +89,17 @@ pub(super) fn note_and_explain_region(
     prefix: &str,
     region: ty::Region<'tcx>,
     suffix: &str,
+    alt_span: Option<Span>,
 ) {
     let (description, span) = match *region {
         ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
-            msg_span_from_free_region(tcx, region)
+            msg_span_from_free_region(tcx, region, alt_span)
         }
 
-        ty::ReEmpty(ty::UniverseIndex::ROOT) => ("the empty lifetime".to_owned(), None),
+        ty::ReEmpty(ty::UniverseIndex::ROOT) => ("the empty lifetime".to_owned(), alt_span),
 
         // uh oh, hope no user ever sees THIS
-        ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), None),
+        ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), alt_span),
 
         ty::RePlaceholder(_) => return,
 
@@ -108,7 +109,7 @@ pub(super) fn note_and_explain_region(
         // We shouldn't really be having unification failures with ReVar
         // and ReLateBound though.
         ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
-            (format!("lifetime {:?}", region), None)
+            (format!("lifetime {:?}", region), alt_span)
         }
     };
 
@@ -122,7 +123,7 @@ pub(super) fn note_and_explain_free_region(
     region: ty::Region<'tcx>,
     suffix: &str,
 ) {
-    let (description, span) = msg_span_from_free_region(tcx, region);
+    let (description, span) = msg_span_from_free_region(tcx, region, None);
 
     emit_msg_span(err, prefix, description, span, suffix);
 }
@@ -130,14 +131,15 @@ pub(super) fn note_and_explain_free_region(
 fn msg_span_from_free_region(
     tcx: TyCtxt<'tcx>,
     region: ty::Region<'tcx>,
+    alt_span: Option<Span>,
 ) -> (String, Option<Span>) {
     match *region {
         ty::ReEarlyBound(_) | ty::ReFree(_) => {
             msg_span_from_early_bound_and_free_regions(tcx, region)
         }
-        ty::ReStatic => ("the static lifetime".to_owned(), None),
-        ty::ReEmpty(ty::UniverseIndex::ROOT) => ("an empty lifetime".to_owned(), None),
-        ty::ReEmpty(ui) => (format!("an empty lifetime in universe {:?}", ui), None),
+        ty::ReStatic => ("the static lifetime".to_owned(), alt_span),
+        ty::ReEmpty(ty::UniverseIndex::ROOT) => ("an empty lifetime".to_owned(), alt_span),
+        ty::ReEmpty(ui) => (format!("an empty lifetime in universe {:?}", ui), alt_span),
         _ => bug!("{:?}", region),
     }
 }
@@ -319,6 +321,7 @@ pub fn unexpected_hidden_region_diagnostic(
                 &format!("hidden type `{}` captures ", hidden_ty),
                 hidden_region,
                 "",
+                None,
             );
         }
     }
@@ -2285,8 +2288,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     &format!("{} must be valid for ", labeled_user_string),
                     sub,
                     "...",
+                    None,
                 );
-                if let Some(infer::RelateParamBound(_, t)) = origin {
+                if let Some(infer::RelateParamBound(_, t, _)) = origin {
                     let return_impl_trait = self
                         .in_progress_typeck_results
                         .map(|typeck_results| typeck_results.borrow().hir_owner)
@@ -2332,6 +2336,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             "first, the lifetime cannot outlive ",
             sup_region,
             "...",
+            None,
         );
 
         debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
@@ -2358,6 +2363,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         "...but the lifetime must also be valid for ",
                         sub_region,
                         "...",
+                        None,
                     );
                     err.span_note(
                         sup_trace.cause.span,
@@ -2379,6 +2385,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             "but, the lifetime must be valid for ",
             sub_region,
             "...",
+            None,
         );
 
         self.note_region_origin(&mut err, &sub_origin);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
index cca19541727..c60a7149e40 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
@@ -43,7 +43,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         multi_span
             .push_span_label(binding_span, "introduces a `'static` lifetime requirement".into());
         err.span_note(multi_span, "because this has an unmet lifetime requirement");
-        note_and_explain_region(self.tcx(), &mut err, "", sup, "...");
+        note_and_explain_region(self.tcx(), &mut err, "", sup, "...", Some(binding_span));
         if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
             // If an impl is local, then maybe this isn't what they want. Try to
             // be as helpful as possible with implicit lifetimes.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index c88869abc29..4bc59a4baf5 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -74,14 +74,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     ),
                 );
             }
-            infer::RelateParamBound(span, t) => {
+            infer::RelateParamBound(span, t, opt_span) => {
                 label_or_note(
                     span,
                     &format!(
-                        "...so that the type `{}` will meet its required lifetime bounds",
-                        self.ty_to_string(t)
+                        "...so that the type `{}` will meet its required lifetime bounds{}",
+                        self.ty_to_string(t),
+                        if opt_span.is_some() { "..." } else { "" },
                     ),
                 );
+                if let Some(span) = opt_span {
+                    err.span_note(span, "...that is required by this bound");
+                }
             }
             infer::RelateRegionParamBound(span) => {
                 label_or_note(
@@ -117,6 +121,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             "",
                             sup,
                             " doesn't meet the lifetime requirements",
+                            None,
                         );
                     }
                     (_, ty::RePlaceholder(_)) => {
@@ -126,16 +131,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             "the required lifetime does not necessarily outlive ",
                             sub,
                             "",
+                            None,
                         );
                     }
                     _ => {
-                        note_and_explain_region(self.tcx, &mut err, "", sup, "...");
+                        note_and_explain_region(self.tcx, &mut err, "", sup, "...", None);
                         note_and_explain_region(
                             self.tcx,
                             &mut err,
                             "...does not necessarily outlive ",
                             sub,
                             "",
+                            None,
                         );
                     }
                 }
@@ -154,6 +161,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "...the reference is valid for ",
                     sub,
                     "...",
+                    None,
                 );
                 note_and_explain_region(
                     self.tcx,
@@ -161,6 +169,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "...but the borrowed content is only valid for ",
                     sup,
                     "",
+                    None,
                 );
                 err
             }
@@ -179,6 +188,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "...the borrowed pointer is valid for ",
                     sub,
                     "...",
+                    None,
                 );
                 note_and_explain_region(
                     self.tcx,
@@ -186,6 +196,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     &format!("...but `{}` is only valid for ", var_name),
                     sup,
                     "",
+                    None,
                 );
                 err
             }
@@ -197,17 +208,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "lifetime of the source pointer does not outlive lifetime bound of the \
                      object type"
                 );
-                note_and_explain_region(self.tcx, &mut err, "object type is valid for ", sub, "");
+                note_and_explain_region(
+                    self.tcx,
+                    &mut err,
+                    "object type is valid for ",
+                    sub,
+                    "",
+                    None,
+                );
                 note_and_explain_region(
                     self.tcx,
                     &mut err,
                     "source pointer is only valid for ",
                     sup,
                     "",
+                    None,
                 );
                 err
             }
-            infer::RelateParamBound(span, ty) => {
+            infer::RelateParamBound(span, ty, opt_span) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,
                     span,
@@ -216,10 +235,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.ty_to_string(ty)
                 );
                 match *sub {
-                    ty::ReStatic => {
-                        note_and_explain_region(self.tcx, &mut err, "type must satisfy ", sub, "")
-                    }
-                    _ => note_and_explain_region(self.tcx, &mut err, "type must outlive ", sub, ""),
+                    ty::ReStatic => note_and_explain_region(
+                        self.tcx,
+                        &mut err,
+                        "type must satisfy ",
+                        sub,
+                        if opt_span.is_some() { " as required by this binding" } else { "" },
+                        opt_span,
+                    ),
+                    _ => note_and_explain_region(
+                        self.tcx,
+                        &mut err,
+                        "type must outlive ",
+                        sub,
+                        if opt_span.is_some() { " as required by this binding" } else { "" },
+                        opt_span,
+                    ),
                 }
                 err
             }
@@ -232,6 +263,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "lifetime parameter instantiated with ",
                     sup,
                     "",
+                    None,
                 );
                 note_and_explain_region(
                     self.tcx,
@@ -239,6 +271,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "but lifetime parameter must outlive ",
                     sub,
                     "",
+                    None,
                 );
                 err
             }
@@ -255,6 +288,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "the return value is only valid for ",
                     sup,
                     "",
+                    None,
                 );
                 err
             }
@@ -266,8 +300,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "a value of type `{}` is borrowed for too long",
                     self.ty_to_string(ty)
                 );
-                note_and_explain_region(self.tcx, &mut err, "the type is valid for ", sub, "");
-                note_and_explain_region(self.tcx, &mut err, "but the borrow lasts for ", sup, "");
+                note_and_explain_region(
+                    self.tcx,
+                    &mut err,
+                    "the type is valid for ",
+                    sub,
+                    "",
+                    None,
+                );
+                note_and_explain_region(
+                    self.tcx,
+                    &mut err,
+                    "but the borrow lasts for ",
+                    sup,
+                    "",
+                    None,
+                );
                 err
             }
             infer::ReferenceOutlivesReferent(ty, span) => {
@@ -278,13 +326,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "in type `{}`, reference has a longer lifetime than the data it references",
                     self.ty_to_string(ty)
                 );
-                note_and_explain_region(self.tcx, &mut err, "the pointer is valid for ", sub, "");
+                note_and_explain_region(
+                    self.tcx,
+                    &mut err,
+                    "the pointer is valid for ",
+                    sub,
+                    "",
+                    None,
+                );
                 note_and_explain_region(
                     self.tcx,
                     &mut err,
                     "but the referenced data is only valid for ",
                     sup,
                     "",
+                    None,
                 );
                 err
             }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index d3bfb2b2e44..f0d63f512fc 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -375,7 +375,7 @@ pub enum SubregionOrigin<'tcx> {
 
     /// Some type parameter was instantiated with the given type,
     /// and that type must outlive some region.
-    RelateParamBound(Span, Ty<'tcx>),
+    RelateParamBound(Span, Ty<'tcx>, Option<Span>),
 
     /// The given region parameter was instantiated with a region
     /// that must outlive some other region.
@@ -1705,7 +1705,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
         match *self {
             Subtype(ref a) => a.span(),
             RelateObjectBound(a) => a,
-            RelateParamBound(a, _) => a,
+            RelateParamBound(a, ..) => a,
             RelateRegionParamBound(a) => a,
             Reborrow(a) => a,
             ReborrowUpvar(a, _) => a,
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 3e2978fd170..437083c68dc 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -64,7 +64,7 @@ use crate::infer::outlives::verify::VerifyBoundCx;
 use crate::infer::{
     self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound,
 };
-use crate::traits::ObligationCause;
+use crate::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::outlives::Component;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
@@ -99,7 +99,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
         cause: &ObligationCause<'tcx>,
     ) {
         let origin = SubregionOrigin::from_obligation_cause(cause, || {
-            infer::RelateParamBound(cause.span, sup_type)
+            infer::RelateParamBound(
+                cause.span,
+                sup_type,
+                match cause.code.peel_derives() {
+                    ObligationCauseCode::BindingObligation(_, span) => Some(*span),
+                    _ => None,
+                },
+            )
         });
 
         self.register_region_obligation(
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs b/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs
index eb11b937143..446a0f8e72f 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs
@@ -99,7 +99,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
             GenericArgKind::Type(t1) => {
                 // we don't actually use this for anything, but
                 // the `TypeOutlives` code needs an origin.
-                let origin = infer::RelateParamBound(DUMMY_SP, t1);
+                let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
 
                 TypeOutlives::new(
                     &mut *self,
diff --git a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
index 987cde191cb..2bccec45894 100644
--- a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
+++ b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
@@ -4,7 +4,13 @@ error[E0310]: the parameter type `U` may not live long enough
 LL | struct Foo<U> {
    |            - help: consider adding an explicit lifetime bound...: `U: 'static`
 LL |     bar: Bar<U>
-   |          ^^^^^^ ...so that the type `U` will meet its required lifetime bounds
+   |          ^^^^^^ ...so that the type `U` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/feature-gate-infer_static_outlives_requirements.rs:7:15
+   |
+LL | struct Bar<T: 'static> {
+   |               ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic-associated-types/issue-86483.stderr b/src/test/ui/generic-associated-types/issue-86483.stderr
index 2106b214fec..f5b92beb3b2 100644
--- a/src/test/ui/generic-associated-types/issue-86483.stderr
+++ b/src/test/ui/generic-associated-types/issue-86483.stderr
@@ -11,7 +11,13 @@ LL | | {
 ...  |
 LL | |
 LL | | }
-   | |_^ ...so that the type `T` will meet its required lifetime bounds
+   | |_^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/issue-86483.rs:7:16
+   |
+LL |     for<'a> T: 'a,
+   |                ^^
 
 error[E0311]: the parameter type `T` may not live long enough
   --> $DIR/issue-86483.rs:9:5
@@ -20,7 +26,13 @@ LL | pub trait IceIce<T>
    |                  - help: consider adding an explicit lifetime bound...: `T: 'a`
 ...
 LL |     type Ice<'v>: IntoIterator<Item = &'v T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/issue-86483.rs:7:16
+   |
+LL |     for<'a> T: 'a,
+   |                ^^
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/issue-86483.rs:9:32
diff --git a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
index d2482b2998b..8237d3718c2 100644
--- a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
+++ b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
@@ -4,7 +4,7 @@ error[E0477]: the type `&'b ()` does not fulfill the required lifetime
 LL |     type Item<'a> = &'b ();
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: type must outlive the lifetime `'a` as defined on the associated item at 8:15
+note: type must outlive the lifetime `'a` as defined on the associated item at 8:15 as required by this binding
   --> $DIR/unsatisfied-outlives-bound.rs:8:15
    |
 LL |     type Item<'a> = &'b ();
@@ -16,7 +16,11 @@ error[E0477]: the type `&'a ()` does not fulfill the required lifetime
 LL |     type Item<'a> = &'a ();
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/unsatisfied-outlives-bound.rs:13:20
+   |
+LL |     type Item<'a>: 'static;
+   |                    ^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-54943.stderr b/src/test/ui/issues/issue-54943.stderr
index 62aacee8111..e917958c05e 100644
--- a/src/test/ui/issues/issue-54943.stderr
+++ b/src/test/ui/issues/issue-54943.stderr
@@ -4,7 +4,11 @@ error[E0477]: the type `&'a u32` does not fulfill the required lifetime
 LL |     let x = foo::<&'a u32>();
    |             ^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/issue-54943.rs:1:11
+   |
+LL | fn foo<T: 'static>() { }
+   |           ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr
index aa72fda3670..b2b70976080 100644
--- a/src/test/ui/kindck/kindck-send-object1.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.stderr
@@ -16,7 +16,11 @@ error[E0477]: the type `&'a (dyn Dummy + Sync + 'a)` does not fulfill the requir
 LL |     assert_send::<&'a (dyn Dummy + Sync)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/kindck-send-object1.rs:5:23
+   |
+LL | fn assert_send<T:Send+'static>() { }
+   |                       ^^^^^^^
 
 error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
   --> $DIR/kindck-send-object1.rs:29:5
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
index eba00c5a945..88253bad194 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
@@ -5,7 +5,12 @@ LL |     bar::<T::Output>()
    |     ^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
-   = note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
+   = note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds...
+note: ...that is required by this bound
+  --> $DIR/projection-where-clause-env-wrong-bound.rs:29:8
+   |
+LL |     T: 'a,
+   |        ^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr
index 34b83859a6b..9f7fc030aa9 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr
@@ -5,7 +5,12 @@ LL |     bar::<<T as MyTrait<'a>>::Output>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
-   = note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
+   = note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds...
+note: ...that is required by this bound
+  --> $DIR/projection-where-clause-env-wrong-lifetime.rs:20:8
+   |
+LL |     T: 'a,
+   |        ^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
index 03da33ae11f..52802848d56 100644
--- a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
+++ b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
@@ -4,7 +4,11 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime
 LL |     type Value = &'a i32;
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:5:17
+   |
+LL |     type Value: 'a;
+   |                 ^^
 
 error[E0477]: the type `&'a i32` does not fulfill the required lifetime
   --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:20:5
@@ -12,7 +16,7 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime
 LL |     type Value = &'a i32;
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-note: type must outlive the lifetime `'b` as defined on the impl at 19:10
+note: type must outlive the lifetime `'b` as defined on the impl at 19:10 as required by this binding
   --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:10
    |
 LL | impl<'a, 'b> Foo<'b> for &'a i64 {
diff --git a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
index d8efeac5b8a..a03210db6df 100644
--- a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
+++ b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
@@ -4,7 +4,11 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime
 LL |     type Value = &'a i32;
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:5:17
+   |
+LL |     type Value: 'static;
+   |                 ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr
index 930bf608ac4..68b90eee72d 100644
--- a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr
+++ b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr
@@ -4,7 +4,11 @@ error[E0477]: the type `&'a isize` does not fulfill the required lifetime
 LL |     assert_send::<&'a isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
+   |
+LL | fn assert_send<T:'static>() { }
+   |                  ^^^^^^^
 
 error[E0477]: the type `&'a str` does not fulfill the required lifetime
   --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5
@@ -12,7 +16,11 @@ error[E0477]: the type `&'a str` does not fulfill the required lifetime
 LL |     assert_send::<&'a str>();
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
+   |
+LL | fn assert_send<T:'static>() { }
+   |                  ^^^^^^^
 
 error[E0477]: the type `&'a [isize]` does not fulfill the required lifetime
   --> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5
@@ -20,7 +28,11 @@ error[E0477]: the type `&'a [isize]` does not fulfill the required lifetime
 LL |     assert_send::<&'a [isize]>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
+   |
+LL | fn assert_send<T:'static>() { }
+   |                  ^^^^^^^
 
 error[E0477]: the type `Box<&'a isize>` does not fulfill the required lifetime
   --> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5
@@ -28,7 +40,11 @@ error[E0477]: the type `Box<&'a isize>` does not fulfill the required lifetime
 LL |     assert_send::<Box<&'a isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
+   |
+LL | fn assert_send<T:'static>() { }
+   |                  ^^^^^^^
 
 error[E0477]: the type `*const &'a isize` does not fulfill the required lifetime
   --> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5
@@ -36,7 +52,11 @@ error[E0477]: the type `*const &'a isize` does not fulfill the required lifetime
 LL |     assert_send::<*const &'a isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
+   |
+LL | fn assert_send<T:'static>() { }
+   |                  ^^^^^^^
 
 error[E0477]: the type `*mut &'a isize` does not fulfill the required lifetime
   --> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5
@@ -44,7 +64,11 @@ error[E0477]: the type `*mut &'a isize` does not fulfill the required lifetime
 LL |     assert_send::<*mut &'a isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: type must satisfy the static lifetime
+note: type must satisfy the static lifetime as required by this binding
+  --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
+   |
+LL | fn assert_send<T:'static>() { }
+   |                  ^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.stderr
index e5a80cbd547..5b692cdcc0e 100644
--- a/src/test/ui/regions/regions-close-object-into-object-5.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-5.stderr
@@ -23,7 +23,13 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |         ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |         ^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/regions-close-object-into-object-5.rs:9:17
+   |
+LL | struct B<'a, T: 'a>(&'a (A<T> + 'a));
+   |                 ^^
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
diff --git a/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr b/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr
index 4ca5ac291d5..97a3947bc0a 100644
--- a/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr
+++ b/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr
@@ -5,7 +5,12 @@ LL |         check_bound(x, self)
    |         ^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `Self: 'a`...
-   = note: ...so that the type `Self` will meet its required lifetime bounds
+   = note: ...so that the type `Self` will meet its required lifetime bounds...
+note: ...that is required by this bound
+  --> $DIR/regions-infer-bound-from-trait-self.rs:12:21
+   |
+LL | fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { }
+   |                     ^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.stderr b/src/test/ui/regions/regions-infer-bound-from-trait.stderr
index 196ee8ca7c0..fd1090d2dbd 100644
--- a/src/test/ui/regions/regions-infer-bound-from-trait.stderr
+++ b/src/test/ui/regions/regions-infer-bound-from-trait.stderr
@@ -4,7 +4,13 @@ error[E0309]: the parameter type `A` may not live long enough
 LL | fn bar1<'a,A>(x: Inv<'a>, a: A) {
    |            - help: consider adding an explicit lifetime bound...: `A: 'a`
 LL |     check_bound(x, a)
-   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
+   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/regions-infer-bound-from-trait.rs:12:21
+   |
+LL | fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { }
+   |                     ^^
 
 error[E0309]: the parameter type `A` may not live long enough
   --> $DIR/regions-infer-bound-from-trait.rs:37:5
@@ -12,7 +18,13 @@ error[E0309]: the parameter type `A` may not live long enough
 LL | fn bar2<'a,'b,A:Is<'b>>(x: Inv<'a>, y: Inv<'b>, a: A) {
    |               -- help: consider adding an explicit lifetime bound...: `A: 'a +`
 LL |     check_bound(x, a)
-   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
+   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/regions-infer-bound-from-trait.rs:12:21
+   |
+LL | fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { }
+   |                     ^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
index a449fac1193..1f387a042e6 100644
--- a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
@@ -4,7 +4,13 @@ error[E0310]: the parameter type `U` may not live long enough
 LL | struct Foo<U> {
    |            - help: consider adding an explicit lifetime bound...: `U: 'static`
 LL |     bar: Bar<U>
-   |          ^^^^^^ ...so that the type `U` will meet its required lifetime bounds
+   |          ^^^^^^ ...so that the type `U` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/dont-infer-static.rs:10:15
+   |
+LL | struct Bar<T: 'static> {
+   |               ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
index 44812a51778..71caeefabac 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
@@ -12,7 +12,13 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | impl<'a, T> Trait<'a, T> for u32 {
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     type Out = RefOk<'a, T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/regions-struct-not-wf.rs:16:20
+   |
+LL | struct RefOk<'a, T:'a> {
+   |                    ^^
 
 error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data it references
   --> $DIR/regions-struct-not-wf.rs:25:5
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
index 589ee1a474a..65aab97d3d7 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
@@ -9,7 +9,7 @@ fn foo(d: impl Debug + 'static) {
 //~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
 }
 
-fn bar(d: impl Debug + 'static) {
+fn bar(d: impl Debug + 'static) { //~ NOTE ...that is required by this bound
     println!("{:?}", d)
 }
 
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
index 9a87129fbf2..fb1848d130f 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
@@ -9,7 +9,7 @@ fn foo(d: impl Debug) {
 //~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
 }
 
-fn bar(d: impl Debug + 'static) {
+fn bar(d: impl Debug + 'static) { //~ NOTE ...that is required by this bound
     println!("{:?}", d)
 }
 
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
index 643dac25724..e4a247993c2 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -5,7 +5,13 @@ LL | fn foo(d: impl Debug) {
    |           ---------- help: consider adding an explicit lifetime bound...: `impl Debug + 'static`
 LL |
 LL |     bar(d);
-   |     ^^^ ...so that the type `impl Debug` will meet its required lifetime bounds
+   |     ^^^ ...so that the type `impl Debug` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/suggest-impl-trait-lifetime.rs:12:24
+   |
+LL | fn bar(d: impl Debug + 'static) {
+   |                        ^^^^^^^
 
 error: aborting due to previous error