about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs40
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed16
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs16
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr16
10 files changed, 63 insertions, 61 deletions
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index a141fdd7b88..774d8078e52 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -87,9 +87,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 /// corresponding place being captured and a String which contains the captured value's
 /// name (i.e: a.b.c)
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-enum CapturesInfo {
+enum UpvarMigrationInfo {
     /// We previously captured all of `x`, but now we capture some sub-path.
-    CapturingLess { source_expr: Option<hir::HirId>, var_name: String },
+    CapturingPrecise { source_expr: Option<hir::HirId>, var_name: String },
     CapturingNothing {
         // where the variable appears in the closure (but is not captured)
         use_span: Span,
@@ -123,7 +123,7 @@ impl MigrationWarningReason {
 
 /// Intermediate format to store information needed to generate a note in the migration lint.
 struct MigrationLintNote {
-    captures_info: CapturesInfo,
+    captures_info: UpvarMigrationInfo,
 
     /// reasons why migration is needed for this capture
     reason: MigrationWarningReason,
@@ -751,14 +751,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // for migration being needed
                         for lint_note in diagnostics_info.iter() {
                             match &lint_note.captures_info {
-                                CapturesInfo::CapturingLess { source_expr: Some(capture_expr_id), var_name: captured_name } => {
+                                UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => {
                                     let cause_span = self.tcx.hir().span(*capture_expr_id);
                                     diagnostics_builder.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
                                         self.tcx.hir().name(*var_hir_id),
                                         captured_name,
                                     ));
                                 }
-                                CapturesInfo::CapturingNothing { use_span } => {
+                                UpvarMigrationInfo::CapturingNothing { use_span } => {
                                     diagnostics_builder.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect",
                                         self.tcx.hir().name(*var_hir_id),
                                     ));
@@ -773,13 +773,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let drop_location_span = drop_location_span(self.tcx, &closure_hir_id);
 
                                 match &lint_note.captures_info {
-                                    CapturesInfo::CapturingLess { var_name: captured_name, .. } => {
+                                    UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
                                         diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure",
                                             self.tcx.hir().name(*var_hir_id),
                                             captured_name,
                                         ));
                                     }
-                                    CapturesInfo::CapturingNothing { use_span: _ } => {
+                                    UpvarMigrationInfo::CapturingNothing { use_span: _ } => {
                                         diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure",
                                             v = self.tcx.hir().name(*var_hir_id),
                                         ));
@@ -791,16 +791,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             for &missing_trait in &lint_note.reason.auto_traits {
                                 // not capturing something anymore cannot cause a trait to fail to be implemented:
                                 match &lint_note.captures_info {
-                                    CapturesInfo::CapturingLess { var_name: captured_name, .. } => {
-                                        diagnostics_builder.span_label(closure_head_span, format!("in Rust 2018, this closure implements {missing_trait} as `{x}` implements {missing_trait}, but in Rust 2021, this closure will no longer implement {missing_trait} as `{p}` does not implement {missing_trait}",
-                                            missing_trait = missing_trait,
-                                            x = self.tcx.hir().name(*var_hir_id),
-                                            p = captured_name,
-                                        ));
+                                    UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
+                                        let var_name = self.tcx.hir().name(*var_hir_id);
+                                        diagnostics_builder.span_label(closure_head_span, format!("\
+                                        in Rust 2018, this closure implements {missing_trait} \
+                                        as `{var_name}` implements {missing_trait}, but in Rust 2021, \
+                                        this closure will no longer implement {missing_trait} \
+                                        because `{var_name}` is not fully captured \
+                                        and `{captured_name}` does not implement {missing_trait}"));
                                     }
 
                                     // Cannot happen: if we don't capture a variable, we impl strictly more traits
-                                    CapturesInfo::CapturingNothing { use_span } => span_bug!(*use_span, "missing trait from not capturing something"),
+                                    UpvarMigrationInfo::CapturingNothing { use_span } => span_bug!(*use_span, "missing trait from not capturing something"),
                                 }
                             }
                         }
@@ -919,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
         var_hir_id: hir::HirId,
         closure_clause: hir::CaptureBy,
-    ) -> Option<FxHashMap<CapturesInfo, FxHashSet<&'static str>>> {
+    ) -> Option<FxHashMap<UpvarMigrationInfo, FxHashSet<&'static str>>> {
         let auto_traits_def_id = vec![
             self.tcx.lang_items().clone_trait(),
             self.tcx.lang_items().sync_trait(),
@@ -1008,7 +1010,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             if !capture_problems.is_empty() {
                 problematic_captures.insert(
-                    CapturesInfo::CapturingLess {
+                    UpvarMigrationInfo::CapturingPrecise {
                         source_expr: capture.info.path_expr_id,
                         var_name: capture.to_string(self.tcx),
                     },
@@ -1042,7 +1044,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
         closure_clause: hir::CaptureBy,
         var_hir_id: hir::HirId,
-    ) -> Option<FxHashSet<CapturesInfo>> {
+    ) -> Option<FxHashSet<UpvarMigrationInfo>> {
         let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
 
         if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
@@ -1068,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let mut diagnostics_info = FxHashSet::default();
                     let upvars = self.tcx.upvars_mentioned(closure_def_id).expect("must be an upvar");
                     let upvar = upvars[&var_hir_id];
-                    diagnostics_info.insert(CapturesInfo::CapturingNothing { use_span: upvar.span });
+                    diagnostics_info.insert(UpvarMigrationInfo::CapturingNothing { use_span: upvar.span });
                     return Some(diagnostics_info);
                 }
                 hir::CaptureBy::Ref => {}
@@ -1086,7 +1088,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Only care about captures that are moved into the closure
                 ty::UpvarCapture::ByValue(..) => {
                     projections_list.push(captured_place.place.projections.as_slice());
-                    diagnostics_info.insert(CapturesInfo::CapturingLess {
+                    diagnostics_info.insert(UpvarMigrationInfo::CapturingPrecise {
                         source_expr: captured_place.info.path_expr_id,
                         var_name: captured_place.to_string(self.tcx),
                     });
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
index b938b842953..26703fbf811 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
@@ -21,7 +21,7 @@ fn test_send_trait() {
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || { let _ = &fptr; unsafe {
         //~^ ERROR: changes to closure capture
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
@@ -41,8 +41,8 @@ fn test_sync_trait() {
     let fptr = SyncPointer(f);
     thread::spawn(move || { let _ = &fptr; unsafe {
         //~^ ERROR: changes to closure capture
-        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` as `fptr.0.0` does not implement `Sync`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0.0` does not implement `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
@@ -67,7 +67,7 @@ fn test_clone_trait() {
     let c = || {
         let _ = &f;
         //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
index bca935843e0..932db51d437 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
@@ -21,7 +21,7 @@ fn test_send_trait() {
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || unsafe {
         //~^ ERROR: changes to closure capture
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
@@ -41,8 +41,8 @@ fn test_sync_trait() {
     let fptr = SyncPointer(f);
     thread::spawn(move || unsafe {
         //~^ ERROR: changes to closure capture
-        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` as `fptr.0.0` does not implement `Sync`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0.0` does not implement `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
@@ -66,7 +66,7 @@ fn test_clone_trait() {
     let f = U(S(Foo(0)), T(0));
     let c = || {
         //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
index 9bdc2f48194..ee4907bb755 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
@@ -2,7 +2,7 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
   --> $DIR/auto_traits.rs:22:19
    |
 LL |     thread::spawn(move || unsafe {
-   |                   ^^^^^^^^^^^^^^ in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
+   |                   ^^^^^^^^^^^^^^ in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr` is not fully captured and `fptr.0` does not implement `Send`
 ...
 LL |         *fptr.0 = 20;
    |         ------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0`
@@ -29,8 +29,8 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^
    |                   |
-   |                   in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` as `fptr.0.0` does not implement `Sync`
-   |                   in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr` is not fully captured and `fptr.0.0` does not implement `Sync`
+   |                   in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr` is not fully captured and `fptr.0.0` does not implement `Send`
 ...
 LL |         *fptr.0.0 = 20;
    |         --------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0`
@@ -50,7 +50,7 @@ error: changes to closure capture in Rust 2021 will affect drop order and which
   --> $DIR/auto_traits.rs:67:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f` is not fully captured and `f.1` does not implement `Clone`
 ...
 LL |         let f_1 = f.1;
    |                   --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.1`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
index 3cb72d679a5..7df0dd76b44 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
@@ -20,8 +20,8 @@ where
     let result = panic::catch_unwind(move || {
         let _ = &f;
         //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
-        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` as `f.0` does not implement `UnwindSafe`
-        //~| NOTE: in Rust 2018, this closure implements `RefUnwindSafe` as `f` implements `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `RefUnwindSafe` as `f.0` does not implement `RefUnwindSafe`
+        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe`
+        //~| NOTE: in Rust 2018, this closure implements `RefUnwindSafe`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
index 783c4034af2..d02fac7c669 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
@@ -19,8 +19,8 @@ where
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || {
         //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
-        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` as `f.0` does not implement `UnwindSafe`
-        //~| NOTE: in Rust 2018, this closure implements `RefUnwindSafe` as `f` implements `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `RefUnwindSafe` as `f.0` does not implement `RefUnwindSafe`
+        //~| NOTE: in Rust 2018, this closure implements `UnwindSafe`
+        //~| NOTE: in Rust 2018, this closure implements `RefUnwindSafe`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
index 6a469db6ebb..74f85b6ebaa 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
@@ -4,8 +4,8 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     let result = panic::catch_unwind(move || {
    |                                      ^^^^^^^
    |                                      |
-   |                                      in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` as `f.0` does not implement `UnwindSafe`
-   |                                      in Rust 2018, this closure implements `RefUnwindSafe` as `f` implements `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `RefUnwindSafe` as `f.0` does not implement `RefUnwindSafe`
+   |                                      in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` because `f` is not fully captured and `f.0` does not implement `UnwindSafe`
+   |                                      in Rust 2018, this closure implements `RefUnwindSafe` as `f` implements `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `RefUnwindSafe` because `f` is not fully captured and `f.0` does not implement `RefUnwindSafe`
 ...
 LL |         f.0()
    |         --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
index 7a7b1ec2321..2b86b0ddade 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed
@@ -37,7 +37,7 @@ fn test_multi_issues() {
     let c = || {
         let _ = (&f1, &f2);
         //~^ ERROR: changes to closure capture in Rust 2021
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1`, `f2` to be fully captured
         let _f_1 = f1.0;
@@ -57,7 +57,7 @@ fn test_capturing_all_disjoint_fields_individually() {
     let c = || {
         let _ = &f1;
         //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_1 = f1.0;
@@ -83,8 +83,8 @@ fn test_capturing_several_disjoint_fields_individually_1() {
     let c = || {
         let _ = &f1;
         //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.2` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -103,7 +103,7 @@ fn test_capturing_several_disjoint_fields_individually_2() {
     let c = || {
         let _ = &f1;
         //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -136,9 +136,9 @@ fn test_multi_traits_issues() {
     let fptr2 = SendPointer(&mut f2 as *mut i32);
     thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe {
         //~^ ERROR: changes to closure capture in Rust 2021
-        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` as `fptr1.0.0` does not implement `Sync`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr1.0.0` does not implement `Send`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr2.0` does not implement `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
         *fptr1.0.0 = 20;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
index 9efe79c5971..3cac4abfad7 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs
@@ -36,7 +36,7 @@ fn test_multi_issues() {
     let f2 = U(S(Foo::from("bar")), T(0));
     let c = || {
         //~^ ERROR: changes to closure capture in Rust 2021
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1`, `f2` to be fully captured
         let _f_1 = f1.0;
@@ -55,7 +55,7 @@ fn test_capturing_all_disjoint_fields_individually() {
     let f1 = U(S(Foo::from("foo")), T(0));
     let c = || {
         //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_1 = f1.0;
@@ -80,8 +80,8 @@ fn test_capturing_several_disjoint_fields_individually_1() {
     let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         //~^ ERROR: changes to closure capture in Rust 2021 will affect which traits the closure implements [rust_2021_incompatible_closure_captures]
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.2` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -99,7 +99,7 @@ fn test_capturing_several_disjoint_fields_individually_2() {
     let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         //~^ ERROR: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements
-        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+        //~| NOTE: in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f1` to be fully captured
         let _f_0 = f1.0;
@@ -132,9 +132,9 @@ fn test_multi_traits_issues() {
     let fptr2 = SendPointer(&mut f2 as *mut i32);
     thread::spawn(move || unsafe {
         //~^ ERROR: changes to closure capture in Rust 2021
-        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` as `fptr1.0.0` does not implement `Sync`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr1.0.0` does not implement `Send`
-        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr2.0` does not implement `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`
+        //~| NOTE: in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
         *fptr1.0.0 = 20;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
index 02492283b7f..0008f1b2c07 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
@@ -2,7 +2,7 @@ error: changes to closure capture in Rust 2021 will affect drop order and which
   --> $DIR/multi_diagnostics.rs:37:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
 ...
 LL |         let _f_1 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -29,7 +29,7 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
   --> $DIR/multi_diagnostics.rs:56:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
 ...
 LL |         let _f_1 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -47,8 +47,8 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     let c = || {
    |             ^^
    |             |
-   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
-   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.2` does not implement `Clone`
+   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
+   |             in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.2` does not implement `Clone`
 ...
 LL |         let _f_0 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -67,7 +67,7 @@ error: changes to closure capture in Rust 2021 will affect drop order and which
   --> $DIR/multi_diagnostics.rs:100:13
    |
 LL |     let c = || {
-   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f1.0` does not implement `Clone`
+   |             ^^ in Rust 2018, this closure implements `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` because `f1` is not fully captured and `f1.0` does not implement `Clone`
 ...
 LL |         let _f_0 = f1.0;
    |                    ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
@@ -94,9 +94,9 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^
    |                   |
-   |                   in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` as `fptr1.0.0` does not implement `Sync`
-   |                   in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr1.0.0` does not implement `Send`
-   |                   in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr2.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Sync`
+   |                   in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr2` is not fully captured and `fptr2.0` does not implement `Send`
 ...
 LL |         *fptr1.0.0 = 20;
    |         ---------- in Rust 2018, this closure captures all of `fptr1`, but in Rust 2021, it will only capture `fptr1.0.0`