about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoxane <roxane.fruytier@hotmail.com>2021-07-07 10:29:06 -0400
committerRoxane <roxane.fruytier@hotmail.com>2021-07-09 10:00:21 -0400
commit2900c1a5e82b9c43917ba4e3e4ca347289b3d21a (patch)
treef45b74edb6e821b74be7610865bfd292ca95af6a
parent0e8e89daa6c53b32e866205fd00ba385c66b90de (diff)
downloadrust-2900c1a5e82b9c43917ba4e3e4ca347289b3d21a.tar.gz
rust-2900c1a5e82b9c43917ba4e3e4ca347289b3d21a.zip
Add note pointing to where a closure and it's captured variables are dropped
-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.stderr31
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr43
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr7
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr9
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed52
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs52
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr101
20 files changed, 373 insertions, 30 deletions
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 3f042dbd4a5..a5c4e161771 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -511,6 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .as_str(),
                     );
                     for (var_hir_id, diagnostics_info) in need_migrations.iter() {
+                        let mut captured_names = format!("");
                         for (captured_hir_id, captured_name) in diagnostics_info.iter() {
                             if let Some(captured_hir_id) = captured_hir_id {
                                 let cause_span = self.tcx.hir().span(*captured_hir_id);
@@ -518,8 +519,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     self.tcx.hir().name(*var_hir_id),
                                     captured_name,
                                 ));
+                                if captured_names == "" {
+                                    captured_names = format!("`{}`", captured_name);
+                                } else {
+                                    captured_names = format!("{}, `{}`", captured_names, captured_name);
+                                }
                             }
                         }
+
+                        if reasons.contains("drop order") {
+                            let drop_location_span = drop_location_span(self.tcx, &closure_hir_id);
+
+                            diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` would be dropped here, but in Rust 2021, only {} would be dropped here alongside the closure",
+                                self.tcx.hir().name(*var_hir_id),
+                                captured_names,
+                            ));
+                        }
                     }
                     diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
                     let closure_body_span = self.tcx.hir().span(body_id.hir_id);
@@ -1350,6 +1365,31 @@ fn apply_capture_kind_on_capture_ty(
     }
 }
 
+/// Returns the Span of where the value with the provided HirId would be dropped
+fn drop_location_span(tcx: TyCtxt<'tcx>, hir_id: &hir::HirId) -> Span {
+    let owner_id = tcx.hir().get_enclosing_scope(*hir_id).unwrap();
+
+    let owner_node = tcx.hir().get(owner_id);
+    match owner_node {
+        hir::Node::Item(item) => match item.kind {
+            hir::ItemKind::Fn(_, _, owner_id) => {
+                let owner_span = tcx.hir().span(owner_id.hir_id);
+                tcx.sess.source_map().end_point(owner_span)
+            }
+            _ => {
+                bug!("Drop location span error: need to handle more ItemKind {:?}", item.kind);
+            }
+        },
+        hir::Node::Block(block) => {
+            let owner_span = tcx.hir().span(block.hir_id);
+            tcx.sess.source_map().end_point(owner_span)
+        }
+        _ => {
+            bug!("Drop location span error: need to handle more Node {:?}", owner_node);
+        }
+    }
+}
+
 struct InferBorrowKind<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, '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 7c7387ff14e..ca55152cc2a 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
@@ -1,5 +1,6 @@
 // run-rustfix
 #![deny(rust_2021_incompatible_closure_captures)]
+//~^ NOTE: the lint level is defined here
 
 use std::thread;
 
@@ -12,8 +13,10 @@ fn test_send_trait() {
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || { let _ = &fptr; unsafe {
         //~^ ERROR: `Send` closure trait implementation
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
+        //~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
     } });
 }
 
@@ -29,8 +32,10 @@ fn test_sync_trait() {
     let fptr = SyncPointer(f);
     thread::spawn(move || { let _ = &fptr; unsafe {
         //~^ ERROR: `Sync`, `Send` closure trait implementation
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
+        //~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
     } });
 }
 
@@ -50,8 +55,10 @@ fn test_clone_trait() {
     let f = U(S(String::from("Hello World")), T(0));
     let c = || { let _ = &f; 
         //~^ ERROR: `Clone` closure trait implementation, and drop order
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
+        //~^ NOTE: in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
         println!("{:?}", f_1.0);
     };
 
@@ -59,6 +66,7 @@ fn test_clone_trait() {
 
     c_clone();
 }
+//~^ NOTE: in Rust 2018, `f` would be dropped here, but in Rust 2021, only `f.1` would be dropped here alongside the closure
 
 fn main() {
     test_send_trait();
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 e606a206b3b..66c43cd865b 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
@@ -1,5 +1,6 @@
 // run-rustfix
 #![deny(rust_2021_incompatible_closure_captures)]
+//~^ NOTE: the lint level is defined here
 
 use std::thread;
 
@@ -12,8 +13,10 @@ fn test_send_trait() {
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || unsafe {
         //~^ ERROR: `Send` closure trait implementation
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
+        //~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
     });
 }
 
@@ -29,8 +32,10 @@ fn test_sync_trait() {
     let fptr = SyncPointer(f);
     thread::spawn(move || unsafe {
         //~^ ERROR: `Sync`, `Send` closure trait implementation
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
+        //~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
     });
 }
 
@@ -50,8 +55,10 @@ fn test_clone_trait() {
     let f = U(S(String::from("Hello World")), T(0));
     let c = || {
         //~^ ERROR: `Clone` closure trait implementation, and drop order
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
+        //~^ NOTE: in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
         println!("{:?}", f_1.0);
     };
 
@@ -59,6 +66,7 @@ fn test_clone_trait() {
 
     c_clone();
 }
+//~^ NOTE: in Rust 2018, `f` would be dropped here, but in Rust 2021, only `f.1` would be dropped here alongside the closure
 
 fn main() {
     test_send_trait();
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 b628c5c3fad..38f8976058d 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
@@ -1,12 +1,14 @@
 error: changes to closure capture in Rust 2021 will affect `Send` closure trait implementation
-  --> $DIR/auto_traits.rs:13:19
+  --> $DIR/auto_traits.rs:14:19
    |
 LL |       thread::spawn(move || unsafe {
    |  ___________________^
 LL | |
 LL | |
+LL | |
 LL | |         *fptr.0 = 20;
    | |         ------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
+LL | |
 LL | |     });
    | |_____^
    |
@@ -21,19 +23,22 @@ help: add a dummy let to cause `fptr` to be fully captured
 LL |     thread::spawn(move || { let _ = &fptr; unsafe {
 LL |
 LL |
+LL |
 LL |         *fptr.0 = 20;
-LL |     } });
-   |
+LL |
+ ...
 
 error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` closure trait implementation
-  --> $DIR/auto_traits.rs:30:19
+  --> $DIR/auto_traits.rs:33:19
    |
 LL |       thread::spawn(move || unsafe {
    |  ___________________^
 LL | |
 LL | |
+LL | |
 LL | |         *fptr.0.0 = 20;
    | |         --------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
+LL | |
 LL | |     });
    | |_____^
    |
@@ -43,22 +48,28 @@ help: add a dummy let to cause `fptr` to be fully captured
 LL |     thread::spawn(move || { let _ = &fptr; unsafe {
 LL |
 LL |
+LL |
 LL |         *fptr.0.0 = 20;
-LL |     } });
-   |
+LL |
+ ...
 
 error: changes to closure capture in Rust 2021 will affect `Clone` closure trait implementation, and drop order
-  --> $DIR/auto_traits.rs:51:13
+  --> $DIR/auto_traits.rs:56:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let f_1 = f.1;
    | |                   --- in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
+LL | |
 LL | |         println!("{:?}", f_1.0);
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `f` would be dropped here, but in Rust 2021, only `f.1` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `f` to be fully captured
@@ -66,10 +77,10 @@ help: add a dummy let to cause `f` to be fully captured
 LL |     let c = || { let _ = &f; 
 LL |
 LL |
+LL |
 LL |         let f_1 = f.1;
-LL |         println!("{:?}", f_1.0);
-LL |     };
-   |
+LL |
+ ...
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed
index 71fa99997d3..e836f27cd7a 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed
@@ -27,6 +27,9 @@ fn test1_all_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
+//~| in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
 
 // String implements drop and therefore should be migrated.
 // But in this test cases, `t2` is completely captured and when it is dropped won't be affected
@@ -48,6 +51,8 @@ fn test2_only_precise_paths_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
 
 // If a variable would've not been captured by value then it would've not been
 // dropped with the closure and therefore doesn't need migration.
@@ -65,6 +70,7 @@ fn test3_only_by_value_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Copy types get copied into the closure instead of move. Therefore we don't need to
 // migrate then as their drop order isn't tied to the closure.
@@ -85,6 +91,7 @@ fn test4_only_non_copy_types_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn test5_only_drop_types_need_migration() {
     struct S(i32, i32);
@@ -105,6 +112,7 @@ fn test5_only_drop_types_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Since we are using a move closure here, both `t` and `t1` get moved
 // even though they are being used by ref inside the closure.
@@ -122,6 +130,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
+//~| in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
 
 // Test migration analysis in case of Drop + Non Drop aggregates.
 // Note we need migration here only because the non-copy (because Drop type) is captured,
@@ -139,6 +149,7 @@ fn test7_drop_non_drop_aggregate_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn main() {
     test1_all_need_migration();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs
index a80aa92aa80..fbf9b983f07 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs
@@ -27,6 +27,9 @@ fn test1_all_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
+//~| in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
 
 // String implements drop and therefore should be migrated.
 // But in this test cases, `t2` is completely captured and when it is dropped won't be affected
@@ -48,6 +51,8 @@ fn test2_only_precise_paths_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
 
 // If a variable would've not been captured by value then it would've not been
 // dropped with the closure and therefore doesn't need migration.
@@ -65,6 +70,7 @@ fn test3_only_by_value_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Copy types get copied into the closure instead of move. Therefore we don't need to
 // migrate then as their drop order isn't tied to the closure.
@@ -85,6 +91,7 @@ fn test4_only_non_copy_types_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn test5_only_drop_types_need_migration() {
     struct S(i32, i32);
@@ -105,6 +112,7 @@ fn test5_only_drop_types_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Since we are using a move closure here, both `t` and `t1` get moved
 // even though they are being used by ref inside the closure.
@@ -122,6 +130,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
+//~| in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
 
 // Test migration analysis in case of Drop + Non Drop aggregates.
 // Note we need migration here only because the non-copy (because Drop type) is captured,
@@ -139,6 +149,7 @@ fn test7_drop_non_drop_aggregate_need_migration() {
 
     c();
 }
+//~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn main() {
     test1_all_need_migration();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
index 11b90a70055..e7b2cd1c553 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
@@ -18,6 +18,13 @@ LL | |         let _t2 = t2.0;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   -
+   |   |
+   |   in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+   |   in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
+   |   in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
    |
 note: the lint level is defined here
   --> $DIR/insignificant_drop.rs:3:9
@@ -36,7 +43,7 @@ LL |         let _t = t.0;
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:38:13
+  --> $DIR/insignificant_drop.rs:41:13
    |
 LL |       let c = || {
    |  _____________^
@@ -52,6 +59,12 @@ LL | |
 LL | |         let _t2 = t2;
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   -
+   |   |
+   |   in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+   |   in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1` to be fully captured
@@ -65,7 +78,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:57:13
+  --> $DIR/insignificant_drop.rs:62:13
    |
 LL |       let c = || {
    |  _____________^
@@ -78,6 +91,9 @@ LL | |
 LL | |         println!("{}", t1.1);
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -91,7 +107,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:77:13
+  --> $DIR/insignificant_drop.rs:83:13
    |
 LL |       let c = || {
    |  _____________^
@@ -104,6 +120,9 @@ LL | |
 LL | |         let _t1 = t1.0;
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -117,7 +136,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:97:13
+  --> $DIR/insignificant_drop.rs:104:13
    |
 LL |       let c = || {
    |  _____________^
@@ -130,6 +149,9 @@ LL | |
 LL | |         let _s = s.0;
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -143,7 +165,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:114:13
+  --> $DIR/insignificant_drop.rs:122:13
    |
 LL |       let c = move || {
    |  _____________^
@@ -158,6 +180,12 @@ LL | |
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   -
+   |   |
+   |   in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
+   |   in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t1`, `t` to be fully captured
@@ -171,7 +199,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:132:13
+  --> $DIR/insignificant_drop.rs:142:13
    |
 LL |       let c = || {
    |  _____________^
@@ -183,6 +211,9 @@ LL | |         let _t = t.0;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed
index f150bd8cc9c..4626c04e9ba 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed
@@ -44,6 +44,7 @@ fn significant_drop_needs_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Even if a type implements an insignificant drop, if it's
 // elements have a significant drop then the overall type is
@@ -63,6 +64,7 @@ fn generic_struct_with_significant_drop_needs_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
 
 fn main() {
     significant_drop_needs_migration();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
index 03c0ab959b2..ebcf1551bac 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
@@ -44,6 +44,7 @@ fn significant_drop_needs_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Even if a type implements an insignificant drop, if it's
 // elements have a significant drop then the overall type is
@@ -63,6 +64,7 @@ fn generic_struct_with_significant_drop_needs_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
 
 fn main() {
     significant_drop_needs_migration();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
index b328abfeb52..97ff0409d0a 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
@@ -11,6 +11,9 @@ LL | |         let _t = t.0;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
 note: the lint level is defined here
   --> $DIR/insignificant_drop_attr_migrations.rs:3:9
@@ -29,7 +32,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop_attr_migrations.rs:56:13
+  --> $DIR/insignificant_drop_attr_migrations.rs:57:13
    |
 LL |       let c = move || {
    |  _____________^
@@ -41,6 +44,9 @@ LL | |         let _t = t.1;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed
index a4a38d47500..f3c15a2e6b6 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed
@@ -22,11 +22,11 @@ fn closure_contains_block() {
         //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
-
     };
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn closure_doesnt_contain_block() {
     let t = (Foo(0), Foo(0));
@@ -38,6 +38,7 @@ fn closure_doesnt_contain_block() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn main() {
     closure_contains_block();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs
index 01a47dffd85..50936d15302 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs
@@ -22,11 +22,11 @@ fn closure_contains_block() {
         //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
-
     };
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn closure_doesnt_contain_block() {
     let t = (Foo(0), Foo(0));
@@ -38,6 +38,7 @@ fn closure_doesnt_contain_block() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 fn main() {
     closure_contains_block();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
index a4426c79a16..09bae6d3f13 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
@@ -9,9 +9,11 @@ LL | |
 LL | |         let _t = t.0;
    | |                  --- in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
 LL | |
-LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
 note: the lint level is defined here
   --> $DIR/migrations_rustfix.rs:2:9
@@ -36,6 +38,9 @@ LL |     let c = || t.0;
    |             ^^^---
    |                |
    |                in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
+...
+LL | }
+   | - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
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 309a3c4a70b..cb3148214b4 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
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![deny(rust_2021_incompatible_closure_captures)]
+//~^ NOTE: the lint level is defined here
 // ignore-wasm32-bare compiled with panic=abort by default
 #![feature(fn_traits)]
 #![feature(never_type)]
@@ -18,8 +19,10 @@ where
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || { let _ = &f; 
         //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` closure trait implementation
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
+        //~^ NOTE: in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.0`
     });
     if let Ok(..) = result {
         panic!("diverging function returned");
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 690e509b318..f6f8ad2c520 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
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![deny(rust_2021_incompatible_closure_captures)]
+//~^ NOTE: the lint level is defined here
 // ignore-wasm32-bare compiled with panic=abort by default
 #![feature(fn_traits)]
 #![feature(never_type)]
@@ -18,8 +19,10 @@ where
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || {
         //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` closure trait implementation
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
+        //~^ NOTE: in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.0`
     });
     if let Ok(..) = result {
         panic!("diverging function returned");
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 3925a0fdb98..9a45e276fcd 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
@@ -1,12 +1,14 @@
 error: changes to closure capture in Rust 2021 will affect `UnwindSafe`, `RefUnwindSafe` closure trait implementation
-  --> $DIR/mir_calls_to_shims.rs:19:38
+  --> $DIR/mir_calls_to_shims.rs:20:38
    |
 LL |       let result = panic::catch_unwind(move || {
    |  ______________________________________^
 LL | |
 LL | |
+LL | |
 LL | |         f.0()
    | |         --- in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.0`
+LL | |
 LL | |     });
    | |_____^
    |
@@ -21,9 +23,10 @@ help: add a dummy let to cause `f` to be fully captured
 LL |     let result = panic::catch_unwind(move || { let _ = &f; 
 LL |
 LL |
+LL |
 LL |         f.0()
-LL |     });
-   |
+LL |
+ ...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
index 00ee8b1f054..7bec8ef06fc 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
@@ -10,6 +10,9 @@ LL | |         let _t = t.0;
 LL | |         let _t = &t.1;
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
 note: the lint level is defined here
   --> $DIR/precise.rs:3:9
@@ -42,6 +45,9 @@ LL | |         let _x = u.1.0;
    | |                  ----- in Rust 2018, closure captures all of `u`, but in Rust 2021, it only captures `u.1.0`
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `u` would be dropped here, but in Rust 2021, only `u.0.1`, `u.0.0`, `u.1.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `u` to be fully captured
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
index 5bdefb6762e..236fdb9e26e 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
@@ -36,6 +36,9 @@ fn test1_all_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
 
 // String implements drop and therefore should be migrated.
 // But in this test cases, `t2` is completely captured and when it is dropped won't be affected
@@ -57,6 +60,8 @@ fn test2_only_precise_paths_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
 
 // If a variable would've not been captured by value then it would've not been
 // dropped with the closure and therefore doesn't need migration.
@@ -74,6 +79,7 @@ fn test3_only_by_value_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // The root variable might not implement drop themselves but some path starting
 // at the root variable might implement Drop.
@@ -92,6 +98,7 @@ fn test4_type_contains_drop_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Test migration analysis in case of Drop + Non Drop aggregates.
 // Note we need migration here only because the non-copy (because Drop type) is captured,
@@ -109,6 +116,7 @@ fn test5_drop_non_drop_aggregate_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Test migration analysis in case of Significant and Insignificant Drop aggregates.
 fn test6_significant_insignificant_drop_aggregate_need_migration() {
@@ -124,6 +132,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
 
 // Since we are using a move closure here, both `t` and `t1` get moved
 // even though they are being used by ref inside the closure.
@@ -142,6 +151,47 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
+
+
+fn test8_drop_order_and_blocks() {
+    {
+        let tuple =
+          (String::from("foo"), String::from("bar"));
+        {
+            let c = || { let _ = &tuple; 
+                //~^ ERROR: drop order
+                //~| NOTE: for more information, see
+                //~| HELP: add a dummy let to cause `tuple` to be fully captured
+                tuple.0;
+                //~^ NOTE: in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
+            };
+
+            c();
+        }
+        //~^ NOTE: in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
+    }
+}
+
+fn test9_drop_order_and_nested_closures() {
+    let tuple =
+        (String::from("foo"), String::from("bar"));
+    let b = || {
+        let c = || { let _ = &tuple; 
+            //~^ ERROR: drop order
+            //~| NOTE: for more information, see
+            //~| HELP: add a dummy let to cause `tuple` to be fully captured
+            tuple.0;
+            //~^ NOTE: in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
+        };
+
+        c();
+    };
+    //~^ NOTE: in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
+
+    b();
+}
 
 fn main() {
     test1_all_need_migration();
@@ -151,4 +201,6 @@ fn main() {
     test5_drop_non_drop_aggregate_need_migration();
     test6_significant_insignificant_drop_aggregate_need_migration();
     test7_move_closures_non_copy_types_might_need_migration();
+    test8_drop_order_and_blocks();
+    test9_drop_order_and_nested_closures();
 }
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
index 44119a76e14..a57f7aa565e 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
@@ -36,6 +36,9 @@ fn test1_all_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
 
 // String implements drop and therefore should be migrated.
 // But in this test cases, `t2` is completely captured and when it is dropped won't be affected
@@ -57,6 +60,8 @@ fn test2_only_precise_paths_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
 
 // If a variable would've not been captured by value then it would've not been
 // dropped with the closure and therefore doesn't need migration.
@@ -74,6 +79,7 @@ fn test3_only_by_value_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // The root variable might not implement drop themselves but some path starting
 // at the root variable might implement Drop.
@@ -92,6 +98,7 @@ fn test4_type_contains_drop_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Test migration analysis in case of Drop + Non Drop aggregates.
 // Note we need migration here only because the non-copy (because Drop type) is captured,
@@ -109,6 +116,7 @@ fn test5_drop_non_drop_aggregate_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
 
 // Test migration analysis in case of Significant and Insignificant Drop aggregates.
 fn test6_significant_insignificant_drop_aggregate_need_migration() {
@@ -124,6 +132,7 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
 
 // Since we are using a move closure here, both `t` and `t1` get moved
 // even though they are being used by ref inside the closure.
@@ -142,6 +151,47 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
 
     c();
 }
+//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
+//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
+
+
+fn test8_drop_order_and_blocks() {
+    {
+        let tuple =
+          (String::from("foo"), String::from("bar"));
+        {
+            let c = || {
+                //~^ ERROR: drop order
+                //~| NOTE: for more information, see
+                //~| HELP: add a dummy let to cause `tuple` to be fully captured
+                tuple.0;
+                //~^ NOTE: in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
+            };
+
+            c();
+        }
+        //~^ NOTE: in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
+    }
+}
+
+fn test9_drop_order_and_nested_closures() {
+    let tuple =
+        (String::from("foo"), String::from("bar"));
+    let b = || {
+        let c = || {
+            //~^ ERROR: drop order
+            //~| NOTE: for more information, see
+            //~| HELP: add a dummy let to cause `tuple` to be fully captured
+            tuple.0;
+            //~^ NOTE: in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
+        };
+
+        c();
+    };
+    //~^ NOTE: in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
+
+    b();
+}
 
 fn main() {
     test1_all_need_migration();
@@ -151,4 +201,6 @@ fn main() {
     test5_drop_non_drop_aggregate_need_migration();
     test6_significant_insignificant_drop_aggregate_need_migration();
     test7_move_closures_non_copy_types_might_need_migration();
+    test8_drop_order_and_blocks();
+    test9_drop_order_and_nested_closures();
 }
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
index f715ea9a48f..13eac4943a4 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
@@ -17,6 +17,13 @@ LL | |         let _t2 = t2.0;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   -
+   |   |
+   |   in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+   |   in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
+   |   in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
    |
 note: the lint level is defined here
   --> $DIR/significant_drop.rs:2:9
@@ -35,7 +42,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/significant_drop.rs:47:13
+  --> $DIR/significant_drop.rs:50:13
    |
 LL |       let c = || {
    |  _____________^
@@ -51,6 +58,12 @@ LL | |
 LL | |         let _t2 = t2;
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   -
+   |   |
+   |   in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
+   |   in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1` to be fully captured
@@ -64,7 +77,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/significant_drop.rs:66:13
+  --> $DIR/significant_drop.rs:71:13
    |
 LL |       let c = || {
    |  _____________^
@@ -77,6 +90,9 @@ LL | |
 LL | |         println!("{:?}", t1.1);
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -90,7 +106,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/significant_drop.rs:85:13
+  --> $DIR/significant_drop.rs:91:13
    |
 LL |       let c = || {
    |  _____________^
@@ -102,6 +118,9 @@ LL | |         let _t = t.0;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -115,7 +134,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/significant_drop.rs:102:13
+  --> $DIR/significant_drop.rs:109:13
    |
 LL |       let c = || {
    |  _____________^
@@ -127,6 +146,9 @@ LL | |         let _t = t.0;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -140,7 +162,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/significant_drop.rs:117:13
+  --> $DIR/significant_drop.rs:125:13
    |
 LL |       let c = || {
    |  _____________^
@@ -152,6 +174,9 @@ LL | |         let _t = t.1;
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   - in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
@@ -165,7 +190,7 @@ LL |
  ...
 
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/significant_drop.rs:134:13
+  --> $DIR/significant_drop.rs:143:13
    |
 LL |       let c = move || {
    |  _____________^
@@ -180,6 +205,12 @@ LL | |
 LL | |
 LL | |     };
    | |_____^
+...
+LL |   }
+   |   -
+   |   |
+   |   in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
+   |   in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t1`, `t` to be fully captured
@@ -192,5 +223,61 @@ LL |         println!("{:?} {:?}", t1.1, t.1);
 LL |
  ...
 
-error: aborting due to 7 previous errors
+error: changes to closure capture in Rust 2021 will affect drop order
+  --> $DIR/significant_drop.rs:163:21
+   |
+LL |               let c = || {
+   |  _____________________^
+LL | |
+LL | |
+LL | |
+LL | |                 tuple.0;
+   | |                 ------- in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
+LL | |
+LL | |             };
+   | |_____________^
+...
+LL |           }
+   |           - in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+help: add a dummy let to cause `tuple` to be fully captured
+   |
+LL |             let c = || { let _ = &tuple; 
+LL |
+LL |
+LL |
+LL |                 tuple.0;
+LL |
+ ...
+
+error: changes to closure capture in Rust 2021 will affect drop order
+  --> $DIR/significant_drop.rs:181:17
+   |
+LL |           let c = || {
+   |  _________________^
+LL | |
+LL | |
+LL | |
+LL | |             tuple.0;
+   | |             ------- in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
+LL | |
+LL | |         };
+   | |_________^
+...
+LL |       };
+   |       - in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+help: add a dummy let to cause `tuple` to be fully captured
+   |
+LL |         let c = || { let _ = &tuple; 
+LL |
+LL |
+LL |
+LL |             tuple.0;
+LL |
+ ...
+
+error: aborting due to 9 previous errors