Add note clarifying why a closure no longer implements a trait

This commit is contained in:
Roxane 2021-07-07 11:04:28 -04:00
parent 2900c1a5e8
commit 36eb5442bd
7 changed files with 46 additions and 10 deletions

View File

@ -535,6 +535,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
captured_names,
));
}
if reasons.contains("closure trait implementation") {
let closure_body_span = self.tcx.hir().span(body_id.hir_id);
let closure_ending_span = self.tcx.sess.source_map().guess_head_span(closure_body_span).shrink_to_lo();
let missing_trait = &reasons[..reasons.find("closure trait implementation").unwrap() - 1];
diagnostics_builder.span_label(closure_ending_span, format!("in Rust 2018, this closure would implement {} as `{}` implements {}, but in Rust 2021, this closure will no longer implement {} as {} does not implement {}",
missing_trait,
self.tcx.hir().name(*var_hir_id),
missing_trait,
missing_trait,
captured_names,
missing_trait,
));
}
}
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);

View File

@ -13,6 +13,7 @@ fn test_send_trait() {
let fptr = SendPointer(&mut f as *mut i32);
thread::spawn(move || { let _ = &fptr; unsafe {
//~^ ERROR: `Send` closure trait implementation
//~| NOTE: in Rust 2018, this closure would implement `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `fptr` to be fully captured
*fptr.0 = 20;
@ -32,6 +33,7 @@ fn test_sync_trait() {
let fptr = SyncPointer(f);
thread::spawn(move || { let _ = &fptr; unsafe {
//~^ ERROR: `Sync`, `Send` closure trait implementation
//~| NOTE: in Rust 2018, this closure would implement `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`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `fptr` to be fully captured
*fptr.0.0 = 20;
@ -55,6 +57,7 @@ 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: in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `f` to be fully captured
let f_1 = f.1;

View File

@ -13,6 +13,7 @@ fn test_send_trait() {
let fptr = SendPointer(&mut f as *mut i32);
thread::spawn(move || unsafe {
//~^ ERROR: `Send` closure trait implementation
//~| NOTE: in Rust 2018, this closure would implement `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `fptr` to be fully captured
*fptr.0 = 20;
@ -32,6 +33,7 @@ fn test_sync_trait() {
let fptr = SyncPointer(f);
thread::spawn(move || unsafe {
//~^ ERROR: `Sync`, `Send` closure trait implementation
//~| NOTE: in Rust 2018, this closure would implement `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`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `fptr` to be fully captured
*fptr.0.0 = 20;
@ -55,6 +57,7 @@ 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: in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `f` to be fully captured
let f_1 = f.1;

View File

@ -2,7 +2,10 @@ error: changes to closure capture in Rust 2021 will affect `Send` closure trait
--> $DIR/auto_traits.rs:14:19
|
LL | thread::spawn(move || unsafe {
| ___________________^
| ^ - in Rust 2018, this closure would implement `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` as `fptr.0` does not implement `Send`
| ___________________|
| |
LL | |
LL | |
LL | |
LL | |
@ -24,15 +27,18 @@ LL | thread::spawn(move || { let _ = &fptr; unsafe {
LL |
LL |
LL |
LL | *fptr.0 = 20;
LL |
LL | *fptr.0 = 20;
...
error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` closure trait implementation
--> $DIR/auto_traits.rs:33:19
--> $DIR/auto_traits.rs:34:19
|
LL | thread::spawn(move || unsafe {
| ___________________^
| ^ - in Rust 2018, this closure would implement `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`
| ___________________|
| |
LL | |
LL | |
LL | |
LL | |
@ -49,15 +55,18 @@ LL | thread::spawn(move || { let _ = &fptr; unsafe {
LL |
LL |
LL |
LL | *fptr.0.0 = 20;
LL |
LL | *fptr.0.0 = 20;
...
error: changes to closure capture in Rust 2021 will affect `Clone` closure trait implementation, and drop order
--> $DIR/auto_traits.rs:56:13
--> $DIR/auto_traits.rs:58:13
|
LL | let c = || {
| _____________^
| ^ - in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure will no longer implement `Clone` as `f.1` does not implement `Clone`
| _____________|
| |
LL | |
LL | |
LL | |
LL | |
@ -78,8 +87,8 @@ LL | let c = || { let _ = &f;
LL |
LL |
LL |
LL | let f_1 = f.1;
LL |
LL | let f_1 = f.1;
...
error: aborting due to 3 previous errors

View File

@ -19,6 +19,7 @@ where
let f = panic::AssertUnwindSafe(f);
let result = panic::catch_unwind(move || { let _ = &f;
//~^ ERROR: `UnwindSafe`, `RefUnwindSafe` closure trait implementation
//~| NOTE: in Rust 2018, this closure would implement `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `f` to be fully captured
f.0()

View File

@ -19,6 +19,7 @@ where
let f = panic::AssertUnwindSafe(f);
let result = panic::catch_unwind(move || {
//~^ ERROR: `UnwindSafe`, `RefUnwindSafe` closure trait implementation
//~| NOTE: in Rust 2018, this closure would implement `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe`
//~| NOTE: for more information, see
//~| HELP: add a dummy let to cause `f` to be fully captured
f.0()

View File

@ -2,7 +2,10 @@ error: changes to closure capture in Rust 2021 will affect `UnwindSafe`, `RefUnw
--> $DIR/mir_calls_to_shims.rs:20:38
|
LL | let result = panic::catch_unwind(move || {
| ______________________________________^
| ^ - in Rust 2018, this closure would implement `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe`
| ______________________________________|
| |
LL | |
LL | |
LL | |
LL | |
@ -24,8 +27,8 @@ LL | let result = panic::catch_unwind(move || { let _ = &f;
LL |
LL |
LL |
LL | f.0()
LL |
LL | f.0()
...
error: aborting due to previous error