diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 8987a51757c..7f26e970e30 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -724,13 +724,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             borrow_span,
             &self.describe_any_place(borrow.borrowed_place.as_ref()),
         );
-
-        borrow_spans.var_span_label(
+        borrow_spans.var_subdiag(
             &mut err,
-            {
+            |var_span| {
+                use crate::session_diagnostics::CaptureVarCause::*;
                 let place = &borrow.borrowed_place;
                 let desc_place = self.describe_any_place(place.as_ref());
-                format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe())
+                match borrow_spans {
+                    UseSpans::ClosureUse { generator_kind, .. } => match generator_kind {
+                        Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
+                        None => BorrowUsePlaceClosure { place: desc_place, var_span },
+                    },
+                    _ => BorrowUsePlace { place: desc_place, var_span },
+                }
             },
             "mutable",
         );
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 534d9ecae6e..61518378e3d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -623,6 +623,26 @@ impl UseSpans<'_> {
         }
     }
 
+    /// Add a subdiagnostic to the use of the captured variable, if it exists.
+    pub(super) fn var_subdiag(
+        self,
+        err: &mut Diagnostic,
+        f: impl Fn(Span) -> crate::session_diagnostics::CaptureVarCause,
+        kind_desc: impl Into<String>,
+    ) {
+        if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self {
+            if capture_kind_span == path_span {
+                err.subdiagnostic(f(capture_kind_span));
+            } else {
+                err.subdiagnostic(crate::session_diagnostics::CaptureVarKind {
+                    kind_desc: kind_desc.into(),
+                    kind_span: capture_kind_span,
+                });
+                err.subdiagnostic(f(path_span));
+            }
+        }
+    }
+
     /// Returns `false` if this place is not used in a closure.
     pub(super) fn for_closure(&self) -> bool {
         match *self {
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index fe24f85fae1..824f20a31bb 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -148,3 +148,33 @@ pub(crate) enum RequireStaticErr {
         multi_span: MultiSpan,
     },
 }
+
+#[derive(Subdiagnostic)]
+#[label(borrowck_capture_kind_label)]
+pub(crate) struct CaptureVarKind {
+    pub kind_desc: String,
+    #[primary_span]
+    pub kind_span: Span,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureVarCause {
+    #[label(borrowck_var_borrow_by_use_place)]
+    BorrowUsePlace {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_borrow_by_use_place_in_generator)]
+    BorrowUsePlaceGenerator {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_borrow_by_use_place_in_closure)]
+    BorrowUsePlaceClosure {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
index 67f2156f32e..80fc4c6e4f5 100644
--- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
@@ -58,3 +58,15 @@ borrowck_returned_lifetime_short =
 
 borrowck_used_impl_require_static =
     the used `impl` has a `'static` requirement
+
+borrowck_capture_kind_label =
+    capture is {$kind_desc} because of use here
+
+borrowck_var_borrow_by_use_place_in_generator =
+    borrow occurs due to use of {$place} in closure in generator
+
+borrowck_var_borrow_by_use_place_in_closure =
+    borrow occurs due to use of {$place} in closure
+
+borrowck_var_borrow_by_use_place =
+    borrow occurs due to use of {$place}