diff options
| author | bors <bors@rust-lang.org> | 2021-05-12 13:33:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-12 13:33:32 +0000 |
| commit | 28e2b29b8952485679367cc05699fb5154f4e5c3 (patch) | |
| tree | 54280248509a198ecaa895cea214166b7a5cb6eb /src | |
| parent | e1ff91f439bc09f566da211c6449821b4e949279 (diff) | |
| parent | 564b4de626d9fa68ce10a0e792c1d329d3225d08 (diff) | |
| download | rust-28e2b29b8952485679367cc05699fb5154f4e5c3.tar.gz rust-28e2b29b8952485679367cc05699fb5154f4e5c3.zip | |
Auto merge of #84730 - sexxi-goose:rox-auto-trait, r=nikomatsakis
Add auto traits and clone trait migrations for RFC2229 This PR - renames the existent RFC2229 migration `disjoint_capture_drop_reorder` to `disjoint_capture_migration` - add additional migrations for auto traits and clone trait Closes rust-lang/project-rfc-2229#29 Closes rust-lang/project-rfc-2229#28 r? `@nikomatsakis`
Diffstat (limited to 'src')
21 files changed, 327 insertions, 19 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 new file mode 100644 index 00000000000..93e6cf03405 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed @@ -0,0 +1,67 @@ +// run-rustfix +#![deny(disjoint_capture_migration)] + +use std::thread; + +/* Test Send Trait Migration */ +struct SendPointer (*mut i32); +unsafe impl Send for SendPointer {} + +fn test_send_trait() { + let mut f = 10; + let fptr = SendPointer(&mut f as *mut i32); + thread::spawn(move || { let _ = &fptr; unsafe { + //~^ ERROR: `Send` trait implementation affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `fptr` to be fully captured + *fptr.0 = 20; + } }); +} + +/* Test Sync Trait Migration */ +struct CustomInt (*mut i32); +struct SyncPointer (CustomInt); +unsafe impl Sync for SyncPointer {} +unsafe impl Send for CustomInt {} + +fn test_sync_trait() { + let mut f = 10; + let f = CustomInt(&mut f as *mut i32); + let fptr = SyncPointer(f); + thread::spawn(move || { let _ = &fptr; unsafe { + //~^ ERROR: `Sync`, `Send` trait implementation affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `fptr` to be fully captured + *fptr.0.0 = 20; + } }); +} + +/* Test Clone Trait Migration */ +struct S(String); +struct T(i32); + +struct U(S,T); + +impl Clone for U { + fn clone(&self) -> Self { + U(S(String::from("Hello World")), T(0)) + } +} + +fn test_clone_trait() { + let f = U(S(String::from("Hello World")), T(0)); + let c = || { let _ = &f; + //~^ ERROR: `Clone` trait implementation, and drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `f` to be fully captured + let f_1 = f.1; + println!("{:?}", f_1.0); + }; + + let c_clone = c.clone(); + + c_clone(); +} + +fn main() { + test_send_trait(); + test_sync_trait(); + test_clone_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 new file mode 100644 index 00000000000..2c0dbd01754 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs @@ -0,0 +1,67 @@ +// run-rustfix +#![deny(disjoint_capture_migration)] + +use std::thread; + +/* Test Send Trait Migration */ +struct SendPointer (*mut i32); +unsafe impl Send for SendPointer {} + +fn test_send_trait() { + let mut f = 10; + let fptr = SendPointer(&mut f as *mut i32); + thread::spawn(move || unsafe { + //~^ ERROR: `Send` trait implementation affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `fptr` to be fully captured + *fptr.0 = 20; + }); +} + +/* Test Sync Trait Migration */ +struct CustomInt (*mut i32); +struct SyncPointer (CustomInt); +unsafe impl Sync for SyncPointer {} +unsafe impl Send for CustomInt {} + +fn test_sync_trait() { + let mut f = 10; + let f = CustomInt(&mut f as *mut i32); + let fptr = SyncPointer(f); + thread::spawn(move || unsafe { + //~^ ERROR: `Sync`, `Send` trait implementation affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `fptr` to be fully captured + *fptr.0.0 = 20; + }); +} + +/* Test Clone Trait Migration */ +struct S(String); +struct T(i32); + +struct U(S,T); + +impl Clone for U { + fn clone(&self) -> Self { + U(S(String::from("Hello World")), T(0)) + } +} + +fn test_clone_trait() { + let f = U(S(String::from("Hello World")), T(0)); + let c = || { + //~^ ERROR: `Clone` trait implementation, and drop order affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `f` to be fully captured + let f_1 = f.1; + println!("{:?}", f_1.0); + }; + + let c_clone = c.clone(); + + c_clone(); +} + +fn main() { + test_send_trait(); + test_sync_trait(); + test_clone_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 new file mode 100644 index 00000000000..6e3723b8bdb --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr @@ -0,0 +1,69 @@ +error: `Send` trait implementation affected for closure because of `capture_disjoint_fields` + --> $DIR/auto_traits.rs:13:19 + | +LL | thread::spawn(move || unsafe { + | ___________________^ +LL | | +LL | | +LL | | *fptr.0 = 20; +LL | | }); + | |_____^ + | +note: the lint level is defined here + --> $DIR/auto_traits.rs:2:9 + | +LL | #![deny(disjoint_capture_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a dummy let to cause `fptr` to be fully captured + | +LL | thread::spawn(move || { let _ = &fptr; unsafe { +LL | +LL | +LL | *fptr.0 = 20; +LL | } }); + | + +error: `Sync`, `Send` trait implementation affected for closure because of `capture_disjoint_fields` + --> $DIR/auto_traits.rs:30:19 + | +LL | thread::spawn(move || unsafe { + | ___________________^ +LL | | +LL | | +LL | | *fptr.0.0 = 20; +LL | | }); + | |_____^ + | +help: add a dummy let to cause `fptr` to be fully captured + | +LL | thread::spawn(move || { let _ = &fptr; unsafe { +LL | +LL | +LL | *fptr.0.0 = 20; +LL | } }); + | + +error: `Clone` trait implementation, and drop order affected for closure because of `capture_disjoint_fields` + --> $DIR/auto_traits.rs:51:13 + | +LL | let c = || { + | _____________^ +LL | | +LL | | +LL | | let f_1 = f.1; +LL | | println!("{:?}", f_1.0); +LL | | }; + | |_____^ + | +help: add a dummy let to cause `f` to be fully captured + | +LL | let c = || { let _ = &f; +LL | +LL | +LL | let f_1 = f.1; +LL | println!("{:?}", f_1.0); +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 300f67e8b1e..3770e93239a 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,6 +1,6 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] //~^ NOTE: the lint level is defined here // Test cases for types that implement a insignificant drop (stlib defined) 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 a17c70d3e28..2015ab7e9b8 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,6 +1,6 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] //~^ NOTE: the lint level is defined here // Test cases for types that implement a insignificant drop (stlib defined) 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 69c12d2bb56..69a99f7a53a 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 @@ -14,8 +14,8 @@ LL | | }; note: the lint level is defined here --> $DIR/insignificant_drop.rs:3:9 | -LL | #![deny(disjoint_capture_drop_reorder)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(disjoint_capture_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured | LL | let c = || { let _ = (&t, &t1, &t2); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs index 3a6af00254c..ee3138ea69e 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs @@ -1,6 +1,6 @@ // run-pass -#![warn(disjoint_capture_drop_reorder)] +#![warn(disjoint_capture_migration)] fn main() { if let a = "" { 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 a3e51a2b8e9..979c023fc53 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 @@ -1,5 +1,5 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] //~^ NOTE: the lint level is defined here // Test the two possible cases for automated migartion using rustfix 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 0eb837b6888..c2a700bd9ca 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 @@ -1,5 +1,5 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] //~^ NOTE: the lint level is defined here // Test the two possible cases for automated migartion using rustfix 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 e6173217edc..a968d3a093b 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 @@ -12,8 +12,8 @@ LL | | }; note: the lint level is defined here --> $DIR/migrations_rustfix.rs:2:9 | -LL | #![deny(disjoint_capture_drop_reorder)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(disjoint_capture_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; 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 new file mode 100644 index 00000000000..95463a62185 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed @@ -0,0 +1,39 @@ +// run-rustfix + +#![deny(disjoint_capture_migration)] +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(fn_traits)] +#![feature(never_type)] + +use std::panic; + +fn foo_diverges() -> ! { panic!() } + +fn assert_panics<F>(f: F) where F: FnOnce() { + let f = panic::AssertUnwindSafe(f); + let result = panic::catch_unwind(move || { let _ = &f; + //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `f` to be fully captured + f.0() + }); + if let Ok(..) = result { + panic!("diverging function returned"); + } +} + +fn test_fn_ptr_panic<T>(mut t: T) + where T: Fn() -> ! +{ + let as_fn = <T as Fn<()>>::call; + assert_panics(|| as_fn(&t, ())); + let as_fn_mut = <T as FnMut<()>>::call_mut; + assert_panics(|| as_fn_mut(&mut t, ())); + let as_fn_once = <T as FnOnce<()>>::call_once; + assert_panics(|| as_fn_once(t, ())); +} + +fn main() { + test_fn_ptr_panic(foo_diverges); + test_fn_ptr_panic(foo_diverges as fn() -> !); +} 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 new file mode 100644 index 00000000000..fae7fc87c02 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs @@ -0,0 +1,39 @@ +// run-rustfix + +#![deny(disjoint_capture_migration)] +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(fn_traits)] +#![feature(never_type)] + +use std::panic; + +fn foo_diverges() -> ! { panic!() } + +fn assert_panics<F>(f: F) where F: FnOnce() { + let f = panic::AssertUnwindSafe(f); + let result = panic::catch_unwind(move || { + //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation affected for closure because of `capture_disjoint_fields` + //~| HELP: add a dummy let to cause `f` to be fully captured + f.0() + }); + if let Ok(..) = result { + panic!("diverging function returned"); + } +} + +fn test_fn_ptr_panic<T>(mut t: T) + where T: Fn() -> ! +{ + let as_fn = <T as Fn<()>>::call; + assert_panics(|| as_fn(&t, ())); + let as_fn_mut = <T as FnMut<()>>::call_mut; + assert_panics(|| as_fn_mut(&mut t, ())); + let as_fn_once = <T as FnOnce<()>>::call_once; + assert_panics(|| as_fn_once(t, ())); +} + +fn main() { + test_fn_ptr_panic(foo_diverges); + test_fn_ptr_panic(foo_diverges as fn() -> !); +} 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 new file mode 100644 index 00000000000..bbc8eb9a9cd --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr @@ -0,0 +1,27 @@ +error: `UnwindSafe`, `RefUnwindSafe` trait implementation affected for closure because of `capture_disjoint_fields` + --> $DIR/mir_calls_to_shims.rs:15:38 + | +LL | let result = panic::catch_unwind(move || { + | ______________________________________^ +LL | | +LL | | +LL | | f.0() +LL | | }); + | |_____^ + | +note: the lint level is defined here + --> $DIR/mir_calls_to_shims.rs:3:9 + | +LL | #![deny(disjoint_capture_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a dummy let to cause `f` to be fully captured + | +LL | let result = panic::catch_unwind(move || { let _ = &f; +LL | +LL | +LL | f.0() +LL | }); + | + +error: aborting due to previous error + diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/no_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/no_migrations.rs index 73592ce04c2..420d66fba5e 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/no_migrations.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/no_migrations.rs @@ -2,7 +2,7 @@ // Set of test cases that don't need migrations -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] // Copy types as copied by the closure instead of being moved into the closure diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed index b739035c784..5c93fce9250 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed @@ -1,6 +1,6 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] #[derive(Debug)] struct Foo(i32); diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs index e1f29c9d0e9..fb4af00aa06 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs @@ -1,6 +1,6 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] #[derive(Debug)] struct Foo(i32); 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 7135ded13c2..0cd191e2c98 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -13,8 +13,8 @@ LL | | }; note: the lint level is defined here --> $DIR/precise.rs:3:9 | -LL | #![deny(disjoint_capture_drop_reorder)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(disjoint_capture_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a dummy let to cause `t` to be fully captured | LL | let c = || { let _ = &t; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs index 8af48501ca2..e3a7220bf09 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs @@ -1,6 +1,6 @@ // run-pass -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] #[derive(Debug)] struct Foo(i32); 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 e1b212153f4..1fa0fb3db2f 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 @@ -1,5 +1,5 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] //~^ NOTE: the lint level is defined here // Test cases for types that implement a significant drop (user defined) 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 106b2933515..1f0efbe1ebc 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 @@ -1,5 +1,5 @@ // run-rustfix -#![deny(disjoint_capture_drop_reorder)] +#![deny(disjoint_capture_migration)] //~^ NOTE: the lint level is defined here // Test cases for types that implement a significant drop (user defined) 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 ee29fe13060..91e75ffb81a 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 @@ -14,8 +14,8 @@ LL | | }; note: the lint level is defined here --> $DIR/significant_drop.rs:2:9 | -LL | #![deny(disjoint_capture_drop_reorder)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(disjoint_capture_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured | LL | let c = || { let _ = (&t, &t1, &t2); |
