about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAman Arora <me@aman-arora.com>2021-09-21 04:05:11 -0400
committerAman Arora <me@aman-arora.com>2021-09-21 04:06:01 -0400
commit1c989880a19b419a00ddaced40a972ce6b8f2c7d (patch)
tree448f77c71efb9dcb7998061d5d63f9c27148b49e
parent099a34cd95bf54e859f7dd03a21fe8202a5e3f70 (diff)
downloadrust-1c989880a19b419a00ddaced40a972ce6b8f2c7d.tar.gz
rust-1c989880a19b419a00ddaced40a972ce6b8f2c7d.zip
Update tests
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed14
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs14
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.fixed12
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.rs12
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed189
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs182
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr161
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed23
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr52
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/macro.fixed11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/macro.rs11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed31
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs31
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr10
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs4
20 files changed, 229 insertions, 559 deletions
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 beebb118399..b0fc5120f08 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
@@ -4,6 +4,14 @@
 
 use std::thread;
 
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
 /* Test Send Trait Migration */
 struct SendPointer(*mut i32);
 unsafe impl Send for SendPointer {}
@@ -42,19 +50,19 @@ fn test_sync_trait() {
 }
 
 /* Test Clone Trait Migration */
-struct S(String);
+struct S(Foo);
 struct T(i32);
 
 struct U(S, T);
 
 impl Clone for U {
     fn clone(&self) -> Self {
-        U(S(String::from("Hello World")), T(0))
+        U(S(Foo(0)), T(0))
     }
 }
 
 fn test_clone_trait() {
-    let f = U(S(String::from("Hello World")), T(0));
+    let f = U(S(Foo(0)), T(0));
     let c = || {
         let _ = &f;
         //~^ ERROR: `Clone` trait implementation for closure and drop order
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 812ecae262f..2bcf9a795ed 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
@@ -4,6 +4,14 @@
 
 use std::thread;
 
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
 /* Test Send Trait Migration */
 struct SendPointer(*mut i32);
 unsafe impl Send for SendPointer {}
@@ -42,19 +50,19 @@ fn test_sync_trait() {
 }
 
 /* Test Clone Trait Migration */
-struct S(String);
+struct S(Foo);
 struct T(i32);
 
 struct U(S, T);
 
 impl Clone for U {
     fn clone(&self) -> Self {
-        U(S(String::from("Hello World")), T(0))
+        U(S(Foo(0)), T(0))
     }
 }
 
 fn test_clone_trait() {
-    let f = U(S(String::from("Hello World")), T(0));
+    let f = U(S(Foo(0)), T(0));
     let c = || {
         //~^ ERROR: `Clone` trait implementation for closure and drop order
         //~| 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`
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 98396abb6ff..8d2d3553d40 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,5 +1,5 @@
 error: changes to closure capture in Rust 2021 will affect `Send` trait implementation for closure
-  --> $DIR/auto_traits.rs:14:19
+  --> $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`
@@ -24,7 +24,7 @@ LL |         *fptr.0 = 20;
  ...
 
 error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` trait implementation for closure
-  --> $DIR/auto_traits.rs:34:19
+  --> $DIR/auto_traits.rs:42:19
    |
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^ in Rust 2018, this closure implements `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure will no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
@@ -44,7 +44,7 @@ LL |         *fptr.0.0 = 20;
  ...
 
 error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
-  --> $DIR/auto_traits.rs:58:13
+  --> $DIR/auto_traits.rs:66: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`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.fixed
index f91454aa211..9a6db588c8b 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.fixed
@@ -3,6 +3,14 @@
 // check-pass
 #![warn(rust_2021_compatibility)]
 
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
 macro_rules! m {
     (@ $body:expr) => {{
         let f = || $body;
@@ -15,11 +23,11 @@ macro_rules! m {
 }
 
 fn main() {
-    let a = (1.to_string(), 2.to_string());
+    let a = (Foo(0), Foo(1));
     m!({
         let _ = &a;
         //~^ HELP: add a dummy
         let x = a.0;
-        println!("{}", x);
+        println!("{:?}", x);
     });
 }
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.rs b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.rs
index 5a1026d0433..08cc24b4b3f 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.rs
@@ -3,6 +3,14 @@
 // check-pass
 #![warn(rust_2021_compatibility)]
 
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
 macro_rules! m {
     (@ $body:expr) => {{
         let f = || $body;
@@ -15,10 +23,10 @@ macro_rules! m {
 }
 
 fn main() {
-    let a = (1.to_string(), 2.to_string());
+    let a = (Foo(0), Foo(1));
     m!({
         //~^ HELP: add a dummy
         let x = a.0;
-        println!("{}", x);
+        println!("{:?}", x);
     });
 }
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
index e6e5598f6d2..a2a9da5f87c 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
@@ -1,5 +1,5 @@
 warning: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/closure-body-macro-fragment.rs:8:17
+  --> $DIR/closure-body-macro-fragment.rs:16:17
    |
 LL |           let f = || $body;
    |  _________________^
@@ -15,7 +15,7 @@ LL | /     m!({
 LL | |
 LL | |         let x = a.0;
    | |                 --- in Rust 2018, this closure captures all of `a`, but in Rust 2021, it will only capture `a.0`
-LL | |         println!("{}", x);
+LL | |         println!("{:?}", x);
 LL | |     });
    | |_______- in this macro invocation
    |
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 c82bc369f43..abcd92eb6b8 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
@@ -1,169 +1,42 @@
+// run-pass
 // run-rustfix
 
 #![deny(rust_2021_incompatible_closure_captures)]
-//~^ NOTE: the lint level is defined here
+#![allow(unused)]
 
-// Test cases for types that implement an insignificant drop (stlib defined)
-
-// `t` needs Drop because one of its elements needs drop,
-// therefore precise capture might affect drop ordering
-fn test1_all_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let t2 = (String::new(), String::new());
-
-    let c = || {
-        let _ = (&t, &t1, &t2);
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
-
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _t1 = t1.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
-        let _t2 = t2.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t2`, but in Rust 2021, it will only capture `t2.0`
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
-//~| in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of 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
-fn test2_only_precise_paths_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let t2 = (String::new(), String::new());
-
-    let c = || {
-        let _ = (&t, &t1);
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _t1 = t1.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
-        let _t2 = t2;
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of 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.
-fn test3_only_by_value_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let c = || {
-        let _ = &t;
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        println!("{}", t1.1);
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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.
-fn test4_only_non_copy_types_need_migration() {
-    let t = (String::new(), String::new());
+#![feature(once_cell)]
 
-    // `t1` is Copy because all of its elements are Copy
-    let t1 = (0i32, 0i32);
-
-    let c = || {
-        let _ = &t;
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _t1 = t1.0;
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-
-fn test5_only_drop_types_need_migration() {
-    struct S(i32, i32);
-
-    let t = (String::new(), String::new());
-
-    // `s` doesn't implement Drop or any elements within it, and doesn't need migration
-    let s = S(0i32, 0i32);
-
-    let c = || {
-        let _ = &t;
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _s = s.0;
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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.
-fn test6_move_closures_non_copy_types_might_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let c = move || {
-        let _ = (&t1, &t);
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
-        println!("{} {}", t1.1, t.1);
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1`
-        //~| NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.1`
-    };
+// Test cases for types that implement an insignificant drop (stlib defined)
 
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
-//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure
+macro_rules! test_insig_dtor_for_type {
+    ($t: ty, $disambiguator: ident) => {
+        mod $disambiguator {
+            use std::collections::*;
+            use std::lazy::SyncOnceCell;
+            use std::rc::Rc;
+            use std::sync::Mutex;
 
-// 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,
-// otherwise we won't need to, since we can get away with just by ref capture in that case.
-fn test7_drop_non_drop_aggregate_need_migration() {
-    let t = (String::new(), String::new(), 0i32);
+            fn _test_for_type(t: $t) {
+                let tup = (Mutex::new(0), t);
 
-    let c = || {
-        let _ = &t;
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
+                let _c = || tup.0;
+            }
+        }
     };
-
-    c();
 }
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
 
-fn main() {
-    test1_all_need_migration();
-    test2_only_precise_paths_need_migration();
-    test3_only_by_value_need_migration();
-    test4_only_non_copy_types_need_migration();
-    test5_only_drop_types_need_migration();
-    test6_move_closures_non_copy_types_might_need_migration();
-    test7_drop_non_drop_aggregate_need_migration();
-}
+test_insig_dtor_for_type!(i32, prim_i32);
+test_insig_dtor_for_type!(Vec<i32>, vec_i32);
+test_insig_dtor_for_type!(String, string);
+test_insig_dtor_for_type!(Vec<String>, vec_string);
+//test_insig_dtor_for_type!(HashMap<String, String>, hash_map);
+test_insig_dtor_for_type!(BTreeMap<String, i32>, btree_map);
+test_insig_dtor_for_type!(LinkedList<String>, linked_list);
+test_insig_dtor_for_type!(Rc<i32>, rc_i32);
+test_insig_dtor_for_type!(Rc<String>, rc_string);
+test_insig_dtor_for_type!(SyncOnceCell<String>, onecell);
+test_insig_dtor_for_type!(std::vec::IntoIter<String>, vec_into_iter);
+test_insig_dtor_for_type!(btree_map::IntoIter<String, String>, btree_map_into_iter);
+test_insig_dtor_for_type!(std::array::IntoIter<String, 5>, array_into_iter);
+
+fn main() {}
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 57ab15ae8f2..abcd92eb6b8 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
@@ -1,162 +1,42 @@
+// run-pass
 // run-rustfix
 
 #![deny(rust_2021_incompatible_closure_captures)]
-//~^ NOTE: the lint level is defined here
+#![allow(unused)]
 
-// Test cases for types that implement an insignificant drop (stlib defined)
-
-// `t` needs Drop because one of its elements needs drop,
-// therefore precise capture might affect drop ordering
-fn test1_all_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let t2 = (String::new(), String::new());
-
-    let c = || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
-
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _t1 = t1.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
-        let _t2 = t2.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t2`, but in Rust 2021, it will only capture `t2.0`
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
-//~| in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of 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
-fn test2_only_precise_paths_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let t2 = (String::new(), String::new());
-
-    let c = || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _t1 = t1.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
-        let _t2 = t2;
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of 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.
-fn test3_only_by_value_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let c = || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        println!("{}", t1.1);
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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.
-fn test4_only_non_copy_types_need_migration() {
-    let t = (String::new(), String::new());
+#![feature(once_cell)]
 
-    // `t1` is Copy because all of its elements are Copy
-    let t1 = (0i32, 0i32);
-
-    let c = || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _t1 = t1.0;
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-
-fn test5_only_drop_types_need_migration() {
-    struct S(i32, i32);
-
-    let t = (String::new(), String::new());
-
-    // `s` doesn't implement Drop or any elements within it, and doesn't need migration
-    let s = S(0i32, 0i32);
-
-    let c = || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-        let _s = s.0;
-    };
-
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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.
-fn test6_move_closures_non_copy_types_might_need_migration() {
-    let t = (String::new(), String::new());
-    let t1 = (String::new(), String::new());
-    let c = move || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
-        println!("{} {}", t1.1, t.1);
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1`
-        //~| NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.1`
-    };
+// Test cases for types that implement an insignificant drop (stlib defined)
 
-    c();
-}
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
-//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure
+macro_rules! test_insig_dtor_for_type {
+    ($t: ty, $disambiguator: ident) => {
+        mod $disambiguator {
+            use std::collections::*;
+            use std::lazy::SyncOnceCell;
+            use std::rc::Rc;
+            use std::sync::Mutex;
 
-// 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,
-// otherwise we won't need to, since we can get away with just by ref capture in that case.
-fn test7_drop_non_drop_aggregate_need_migration() {
-    let t = (String::new(), String::new(), 0i32);
+            fn _test_for_type(t: $t) {
+                let tup = (Mutex::new(0), t);
 
-    let c = || {
-        //~^ ERROR: drop order
-        //~| NOTE: for more information, see
-        //~| HELP: add a dummy let to cause `t` to be fully captured
-        let _t = t.0;
-        //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
+                let _c = || tup.0;
+            }
+        }
     };
-
-    c();
 }
-//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
 
-fn main() {
-    test1_all_need_migration();
-    test2_only_precise_paths_need_migration();
-    test3_only_by_value_need_migration();
-    test4_only_non_copy_types_need_migration();
-    test5_only_drop_types_need_migration();
-    test6_move_closures_non_copy_types_might_need_migration();
-    test7_drop_non_drop_aggregate_need_migration();
-}
+test_insig_dtor_for_type!(i32, prim_i32);
+test_insig_dtor_for_type!(Vec<i32>, vec_i32);
+test_insig_dtor_for_type!(String, string);
+test_insig_dtor_for_type!(Vec<String>, vec_string);
+//test_insig_dtor_for_type!(HashMap<String, String>, hash_map);
+test_insig_dtor_for_type!(BTreeMap<String, i32>, btree_map);
+test_insig_dtor_for_type!(LinkedList<String>, linked_list);
+test_insig_dtor_for_type!(Rc<i32>, rc_i32);
+test_insig_dtor_for_type!(Rc<String>, rc_string);
+test_insig_dtor_for_type!(SyncOnceCell<String>, onecell);
+test_insig_dtor_for_type!(std::vec::IntoIter<String>, vec_into_iter);
+test_insig_dtor_for_type!(btree_map::IntoIter<String, String>, btree_map_into_iter);
+test_insig_dtor_for_type!(std::array::IntoIter<String, 5>, array_into_iter);
+
+fn main() {}
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
deleted file mode 100644
index 7989a8fa5cc..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
+++ /dev/null
@@ -1,161 +0,0 @@
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:15:13
-   |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-LL |
-LL |         let _t1 = t1.0;
-   |                   ---- in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
-LL |
-LL |         let _t2 = t2.0;
-   |                   ---- in Rust 2018, this closure captures all of `t2`, but in Rust 2021, it will only capture `t2.0`
-...
-LL | }
-   | -
-   | |
-   | in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-   | in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
-   | in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure
-   |
-note: the lint level is defined here
-  --> $DIR/insignificant_drop.rs:3:9
-   |
-LL | #![deny(rust_2021_incompatible_closure_captures)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = 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`, `t2` to be fully captured
-   |
-LL ~     let c = || {
-LL +         let _ = (&t, &t1, &t2);
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:41:13
-   |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-LL |
-LL |         let _t1 = t1.0;
-   |                   ---- in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
-...
-LL | }
-   | -
-   | |
-   | in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
-   | in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of 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
-   |
-LL ~     let c = || {
-LL +         let _ = (&t, &t1);
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:62:13
-   |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-...
-LL | }
-   | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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
-   |
-LL ~     let c = || {
-LL +         let _ = &t;
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:83:13
-   |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-...
-LL | }
-   | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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
-   |
-LL ~     let c = || {
-LL +         let _ = &t;
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:104:13
-   |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-...
-LL | }
-   | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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
-   |
-LL ~     let c = || {
-LL +         let _ = &t;
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:122:13
-   |
-LL |     let c = move || {
-   |             ^^^^^^^
-...
-LL |         println!("{} {}", t1.1, t.1);
-   |                           ----  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1`
-   |                           |
-   |                           in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.1`
-...
-LL | }
-   | -
-   | |
-   | in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure
-   | in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of 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
-   |
-LL ~     let c = move || {
-LL +         let _ = (&t1, &t);
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop.rs:142:13
-   |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-...
-LL | }
-   | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of 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
-   |
-LL ~     let c = || {
-LL +         let _ = &t;
-   |
-
-error: aborting due to 7 previous errors
-
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 e672d9266fc..0787ac7c77b 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
@@ -5,9 +5,11 @@
 #![feature(rustc_attrs)]
 #![allow(unused)]
 
+    use std::sync::Mutex;
+
 struct InsignificantDropPoint {
     x: i32,
-    y: i32,
+    y: Mutex<T>,
 }
 
 impl Drop for InsignificantDropPoint {
@@ -15,7 +17,7 @@ impl Drop for InsignificantDropPoint {
     fn drop(&mut self) {}
 }
 
-struct SigDrop;
+struct SigDrop { x: () }
 
 impl Drop for SigDrop {
     fn drop(&mut self) {}
@@ -30,12 +32,22 @@ impl<T> Drop for GenericStruct<T> {
     fn drop(&mut self) {}
 }
 
+// Test no migration because InsignificantDropPoint is marked as insignificant
+fn insign_dtor() {
+    let t = (
+        InsignificantDropPoint { x: 0, y: Mutex::new(0) },
+        InsignificantDropPoint { x: 0, y: Mutex::new(0) }
+    );
+
+    let c = || t.0;
+
+}
+
 // `SigDrop` implements drop and therefore needs to be migrated.
 fn significant_drop_needs_migration() {
-    let t = (SigDrop {}, SigDrop {});
+    let t = (SigDrop { x: () }, SigDrop { x: () });
 
     let c = || {
-        let _ = &t;
         //~^ ERROR: drop order
         //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `t` to be fully captured
@@ -52,11 +64,10 @@ fn significant_drop_needs_migration() {
 // consdered to have an significant drop. Since the elements
 // of `GenericStruct` implement drop, migration is required.
 fn generic_struct_with_significant_drop_needs_migration() {
-    let t = Wrapper(GenericStruct(SigDrop {}, SigDrop {}), 5);
+    let t = Wrapper(GenericStruct(SigDrop { x: () }, SigDrop { x: () }), 5);
 
     // move is used to force i32 to be copied instead of being a ref
     let c = move || {
-        let _ = &t;
         //~^ ERROR: drop order
         //~| NOTE: for more information, see
         //~| 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.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
index 45850ec5f36..ff7af685ea5 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
@@ -5,9 +5,11 @@
 #![feature(rustc_attrs)]
 #![allow(unused)]
 
+    use std::sync::Mutex;
+
 struct InsignificantDropPoint {
     x: i32,
-    y: i32,
+    y: Mutex<i32>,
 }
 
 impl Drop for InsignificantDropPoint {
@@ -30,6 +32,17 @@ impl<T> Drop for GenericStruct<T> {
     fn drop(&mut self) {}
 }
 
+// Test no migration because InsignificantDropPoint is marked as insignificant
+fn insign_dtor() {
+    let t = (
+        InsignificantDropPoint { x: 0, y: Mutex::new(0) },
+        InsignificantDropPoint { x: 0, y: Mutex::new(0) }
+    );
+
+    let c = || t.0;
+
+}
+
 // `SigDrop` implements drop and therefore needs to be migrated.
 fn significant_drop_needs_migration() {
     let t = (SigDrop {}, SigDrop {});
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 961834aca19..80289d6289d 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
@@ -1,45 +1,19 @@
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop_attr_migrations.rs:37:13
+error[E0107]: missing generics for struct `Mutex`
+  --> $DIR/insignificant_drop_attr_migrations.rs:12:8
    |
-LL |     let c = || {
-   |             ^^
-...
-LL |         let _t = t.0;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
-...
-LL | }
-   | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
+LL |     y: Mutex,
+   |        ^^^^^ expected 1 generic argument
    |
-note: the lint level is defined here
-  --> $DIR/insignificant_drop_attr_migrations.rs:3:9
+note: struct defined here, with 1 generic parameter: `T`
+  --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
    |
-LL | #![deny(rust_2021_incompatible_closure_captures)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = 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
-   |
-LL ~     let c = || {
-LL +         let _ = &t;
-   |
-
-error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/insignificant_drop_attr_migrations.rs:57:13
-   |
-LL |     let c = move || {
-   |             ^^^^^^^
-...
-LL |         let _t = t.1;
-   |                  --- in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1`
-...
-LL | }
-   | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of 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
-   |
-LL ~     let c = move || {
-LL +         let _ = &t;
+LL | pub struct Mutex<T: ?Sized> {
+   |            ^^^^^ -
+help: add missing generic argument
    |
+LL |     y: Mutex<T>,
+   |        ~~~~~~~~
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/macro.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/macro.fixed
index b9dd8a20b09..31fe494dc79 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/macro.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/macro.fixed
@@ -5,8 +5,17 @@
 #![deny(rust_2021_incompatible_closure_captures)]
 //~^ NOTE: the lint level is defined here
 
+
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
 fn main() {
-    let a = ("hey".to_string(), "123".to_string());
+    let a = (Foo(0), Foo(1));
     let _ = || { let _ = &a; dbg!(a.0) };
     //~^ ERROR: drop order
     //~| NOTE: will only capture `a.0`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/macro.rs b/src/test/ui/closures/2229_closure_analysis/migrations/macro.rs
index f7ccdb754b8..0f0c4974922 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/macro.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/macro.rs
@@ -5,8 +5,17 @@
 #![deny(rust_2021_incompatible_closure_captures)]
 //~^ NOTE: the lint level is defined here
 
+
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
 fn main() {
-    let a = ("hey".to_string(), "123".to_string());
+    let a = (Foo(0), Foo(1));
     let _ = || dbg!(a.0);
     //~^ ERROR: drop order
     //~| NOTE: will only capture `a.0`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr
index d1f959dfc52..5046a4bcbb4 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr
@@ -1,5 +1,5 @@
 error: changes to closure capture in Rust 2021 will affect drop order
-  --> $DIR/macro.rs:10:13
+  --> $DIR/macro.rs:19:13
    |
 LL |     let _ = || dbg!(a.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 ef90257474a..11218eff133 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
@@ -4,7 +4,22 @@
 
 use std::thread;
 
-struct S(String);
+#[derive(Debug)]
+struct Foo(String);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
+impl Foo {
+    fn from(s: &str) -> Self {
+        Self(String::from(s))
+    }
+}
+
+
+struct S(Foo);
 
 #[derive(Clone)]
 struct T(i32);
@@ -13,13 +28,13 @@ struct U(S, T);
 
 impl Clone for U {
     fn clone(&self) -> Self {
-        U(S(String::from("Hello World")), T(0))
+        U(S(Foo::from("Hello World")), T(0))
     }
 }
 
 fn test_multi_issues() {
-    let f1 = U(S(String::from("foo")), T(0));
-    let f2 = U(S(String::from("bar")), T(0));
+    let f1 = U(S(Foo::from("foo")), T(0));
+    let f2 = U(S(Foo::from("bar")), T(0));
     let c = || {
         let _ = (&f1, &f2);
         //~^ ERROR: `Clone` trait implementation for closure and drop order
@@ -39,7 +54,7 @@ fn test_multi_issues() {
 //~^ NOTE: in Rust 2018, `f2` is dropped here, but in Rust 2021, only `f2.1` will be dropped here as part of the closure
 
 fn test_capturing_all_disjoint_fields_individually() {
-    let f1 = U(S(String::from("foo")), T(0));
+    let f1 = U(S(Foo::from("foo")), T(0));
     let c = || {
         let _ = &f1;
         //~^ ERROR: `Clone` trait implementation for closure
@@ -60,12 +75,12 @@ struct U1(S, T, S);
 
 impl Clone for U1 {
     fn clone(&self) -> Self {
-        U1(S(String::from("foo")), T(0), S(String::from("bar")))
+        U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")))
     }
 }
 
 fn test_capturing_several_disjoint_fields_individually_1() {
-    let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
+    let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         let _ = &f1;
         //~^ ERROR: `Clone` trait implementation for closure
@@ -85,7 +100,7 @@ fn test_capturing_several_disjoint_fields_individually_1() {
 }
 
 fn test_capturing_several_disjoint_fields_individually_2() {
-    let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
+    let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         let _ = &f1;
         //~^ ERROR: `Clone` trait implementation for closure and drop order
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 b9644c18d28..02f2faa2e87 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
@@ -4,7 +4,22 @@
 
 use std::thread;
 
-struct S(String);
+#[derive(Debug)]
+struct Foo(String);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
+impl Foo {
+    fn from(s: &str) -> Self {
+        Self(String::from(s))
+    }
+}
+
+
+struct S(Foo);
 
 #[derive(Clone)]
 struct T(i32);
@@ -13,13 +28,13 @@ struct U(S, T);
 
 impl Clone for U {
     fn clone(&self) -> Self {
-        U(S(String::from("Hello World")), T(0))
+        U(S(Foo::from("Hello World")), T(0))
     }
 }
 
 fn test_multi_issues() {
-    let f1 = U(S(String::from("foo")), T(0));
-    let f2 = U(S(String::from("bar")), T(0));
+    let f1 = U(S(Foo::from("foo")), T(0));
+    let f2 = U(S(Foo::from("bar")), T(0));
     let c = || {
         //~^ ERROR: `Clone` trait implementation for closure and drop order
         //~| 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`
@@ -38,7 +53,7 @@ fn test_multi_issues() {
 //~^ NOTE: in Rust 2018, `f2` is dropped here, but in Rust 2021, only `f2.1` will be dropped here as part of the closure
 
 fn test_capturing_all_disjoint_fields_individually() {
-    let f1 = U(S(String::from("foo")), T(0));
+    let f1 = U(S(Foo::from("foo")), T(0));
     let c = || {
         //~^ ERROR: `Clone` trait implementation for closure
         //~| 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`
@@ -58,12 +73,12 @@ struct U1(S, T, S);
 
 impl Clone for U1 {
     fn clone(&self) -> Self {
-        U1(S(String::from("foo")), T(0), S(String::from("bar")))
+        U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")))
     }
 }
 
 fn test_capturing_several_disjoint_fields_individually_1() {
-    let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
+    let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         //~^ ERROR: `Clone` trait implementation for closure
         //~| 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`
@@ -82,7 +97,7 @@ fn test_capturing_several_disjoint_fields_individually_1() {
 }
 
 fn test_capturing_several_disjoint_fields_individually_2() {
-    let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
+    let f1 = U1(S(Foo::from("foo")), T(0), S(Foo::from("bar")));
     let c = || {
         //~^ ERROR: `Clone` trait implementation for closure and drop order
         //~| 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`
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 8bee950c13e..d425db5aa99 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
@@ -1,5 +1,5 @@
 error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
-  --> $DIR/multi_diagnostics.rs:23:13
+  --> $DIR/multi_diagnostics.rs:38: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`
@@ -26,7 +26,7 @@ LL +         let _ = (&f1, &f2);
    |
 
 error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure
-  --> $DIR/multi_diagnostics.rs:42:13
+  --> $DIR/multi_diagnostics.rs:57: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`
@@ -42,7 +42,7 @@ LL +         let _ = &f1;
    |
 
 error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure
-  --> $DIR/multi_diagnostics.rs:67:13
+  --> $DIR/multi_diagnostics.rs:82:13
    |
 LL |     let c = || {
    |             ^^
@@ -64,7 +64,7 @@ LL +         let _ = &f1;
    |
 
 error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
-  --> $DIR/multi_diagnostics.rs:86:13
+  --> $DIR/multi_diagnostics.rs:101: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`
@@ -89,7 +89,7 @@ LL +         let _ = &f1;
    |
 
 error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` trait implementation for closure
-  --> $DIR/multi_diagnostics.rs:119:19
+  --> $DIR/multi_diagnostics.rs:134:19
    |
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^
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 aca0b2a96ac..d3ede331313 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
@@ -165,7 +165,7 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
 fn test8_drop_order_and_blocks() {
     {
         let tuple =
-          (String::from("foo"), String::from("bar"));
+          (Foo(0), Foo(1));
         {
             let c = || {
                 let _ = &tuple;
@@ -184,7 +184,7 @@ fn test8_drop_order_and_blocks() {
 
 fn test9_drop_order_and_nested_closures() {
     let tuple =
-        (String::from("foo"), String::from("bar"));
+        (Foo(0), Foo(1));
     let b = || {
         let c = || {
             let _ = &tuple;
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 fd4134a7704..d0046895987 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
@@ -158,7 +158,7 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
 fn test8_drop_order_and_blocks() {
     {
         let tuple =
-          (String::from("foo"), String::from("bar"));
+          (Foo(0), Foo(1));
         {
             let c = || {
                 //~^ ERROR: drop order
@@ -176,7 +176,7 @@ fn test8_drop_order_and_blocks() {
 
 fn test9_drop_order_and_nested_closures() {
     let tuple =
-        (String::from("foo"), String::from("bar"));
+        (Foo(0), Foo(1));
     let b = || {
         let c = || {
             //~^ ERROR: drop order