diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 46c0bbac2f1..60860f93daa 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -715,22 +715,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             borrow_span,
             &self.describe_any_place(borrow.borrowed_place.as_ref()),
         );
-        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());
-                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",
-        );
+        borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
+            use crate::session_diagnostics::CaptureVarCause::*;
+            let place = &borrow.borrowed_place;
+            let desc_place = self.describe_any_place(place.as_ref());
+            match kind {
+                Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
+                None => BorrowUsePlaceClosure { place: desc_place, var_span },
+            }
+        });
 
         self.explain_why_borrow_contains_point(location, borrow, None)
             .add_explanation_to_diagnostic(
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index c7b9f617d5a..7f26af67c71 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -650,19 +650,28 @@ impl UseSpans<'_> {
     pub(super) fn var_subdiag(
         self,
         err: &mut Diagnostic,
-        f: impl Fn(Span) -> crate::session_diagnostics::CaptureVarCause,
-        kind_desc: impl Into<String>,
+        kind: Option<rustc_middle::mir::BorrowKind>,
+        f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause,
     ) {
-        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,
+        use crate::session_diagnostics::CaptureVarKind::*;
+        if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self {
+            if capture_kind_span != path_span {
+                err.subdiagnostic(match kind {
+                    Some(kd) => match kd {
+                        rustc_middle::mir::BorrowKind::Shared
+                        | rustc_middle::mir::BorrowKind::Shallow
+                        | rustc_middle::mir::BorrowKind::Unique => {
+                            Immute { kind_span: capture_kind_span }
+                        }
+
+                        rustc_middle::mir::BorrowKind::Mut { .. } => {
+                            Mut { kind_span: capture_kind_span }
+                        }
+                    },
+                    None => Move { kind_span: capture_kind_span },
                 });
-                err.subdiagnostic(f(path_span));
-            }
+            };
+            err.subdiagnostic(f(generator_kind, path_span));
         }
     }
 
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 62c11e303b8..3f9bfc5373a 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -149,36 +149,6 @@ pub(crate) enum RequireStaticErr {
     },
 }
 
-#[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,
-    },
-}
-
 #[derive(Subdiagnostic)]
 pub(crate) enum CaptureVarPathUseCause {
     #[label(borrowck_borrow_due_to_use_generator)]
@@ -222,3 +192,38 @@ pub(crate) enum CaptureVarPathUseCause {
         path_span: Span,
     },
 }
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureVarKind {
+    #[label(borrowck_capture_immute)]
+    Immute {
+        #[primary_span]
+        kind_span: Span,
+    },
+    #[label(borrowck_capture_mut)]
+    Mut {
+        #[primary_span]
+        kind_span: Span,
+    },
+    #[label(borrowck_capture_move)]
+    Move {
+        #[primary_span]
+        kind_span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureVarCause {
+    #[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 5d6617d5bcc..e3174360c90 100644
--- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
@@ -94,3 +94,18 @@ borrowck_assign_due_to_use_closure =
 
 borrowck_assign_part_due_to_use_closure =
     assign to part occurs due to use in closure
+
+borrowck_capture_immute =
+    capture is immutable because of use here
+
+borrowck_capture_mut =
+    capture is mutable because of use here
+
+borrowck_capture_move =
+    capture is moved because of use here
+
+borrowck_var_move_by_use_place_in_generator =
+    move occurs due to use of {$place} in generator
+
+borrowck_var_move_by_use_place_in_closure =
+    move occurs due to use of {$place} in closure
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 0a96d23e354..35675313b48 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1898,6 +1898,7 @@ impl BorrowKind {
         }
     }
 
+    // FIXME: won't be used after diagnostic migration
     pub fn describe_mutability(&self) -> &str {
         match *self {
             BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => "immutable",