You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #86965 - sexxi-goose:rfc2229-improve-lint, r=nikomatsakis,lqd
Improves migrations lint for RFC2229
This PR improves the current disjoint capture migration lint by providing more information on why drop order or auto trait implementation for a closure is impacted by the use of the new feature.
The drop order migration lint will now look something like this:
```
error: changes to closure capture in Rust 2021 will affect drop order
--> $DIR/significant_drop.rs:163:21
|
LL | let c = || {
| ^^
...
LL | tuple.0;
| ------- in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
...
LL | }
| - in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
```
The auto trait migration lint will now look something like this:
```
error: changes to closure capture in Rust 2021 will affect `Send` trait implementation for closure
--> $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 would no longer implement `Send` as `fptr.0` does not implement `Send`
...
LL | *fptr.0 = 20;
| ------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
```
r? `@nikomatsakis`
Closesrust-lang/project-rfc-2229#54
Copy file name to clipboardExpand all lines: src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
+14-3
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,6 @@
1
1
// run-rustfix
2
2
#![deny(rust_2021_incompatible_closure_captures)]
3
+
//~^ NOTE: the lint level is defined here
3
4
4
5
use std::thread;
5
6
@@ -11,9 +12,12 @@ fn test_send_trait() {
11
12
let mut f = 10;
12
13
let fptr = SendPointer(&mut f as *mut i32);
13
14
thread::spawn(move || { let _ = &fptr; unsafe {
14
-
//~^ ERROR: `Send` trait implementation
15
+
//~^ ERROR: `Send` trait implementation for closure
16
+
//~| NOTE: in Rust 2018, this closure would implement `Send` as `fptr` implements `Send`, but in Rust 2021, this closure would no longer implement `Send` as `fptr.0` does not implement `Send`
17
+
//~| NOTE: for more information, see
15
18
//~| HELP: add a dummy let to cause `fptr` to be fully captured
16
19
*fptr.0 = 20;
20
+
//~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
17
21
} });
18
22
}
19
23
@@ -28,9 +32,12 @@ fn test_sync_trait() {
28
32
let f = CustomInt(&mut f as *mut i32);
29
33
let fptr = SyncPointer(f);
30
34
thread::spawn(move || { let _ = &fptr; unsafe {
31
-
//~^ ERROR: `Sync`, `Send` trait implementation
35
+
//~^ ERROR: `Sync`, `Send` trait implementation for closure
36
+
//~| NOTE: in Rust 2018, this closure would implement `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure would no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
37
+
//~| NOTE: for more information, see
32
38
//~| HELP: add a dummy let to cause `fptr` to be fully captured
33
39
*fptr.0.0 = 20;
40
+
//~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
34
41
} });
35
42
}
36
43
@@ -49,16 +56,20 @@ impl Clone for U {
49
56
fn test_clone_trait() {
50
57
let f = U(S(String::from("Hello World")), T(0));
51
58
let c = || { let _ = &f;
52
-
//~^ ERROR: `Clone` trait implementation, and drop order
59
+
//~^ ERROR: `Clone` trait implementation for closure and drop order
60
+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f.1` does not implement `Clone`
61
+
//~| NOTE: for more information, see
53
62
//~| HELP: add a dummy let to cause `f` to be fully captured
54
63
let f_1 = f.1;
64
+
//~^ NOTE: in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
55
65
println!("{:?}", f_1.0);
56
66
};
57
67
58
68
let c_clone = c.clone();
59
69
60
70
c_clone();
61
71
}
72
+
//~^ NOTE: in Rust 2018, `f` would be dropped here, but in Rust 2021, only `f.1` would be dropped here alongside the closure
Copy file name to clipboardExpand all lines: src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
+14-3
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,6 @@
1
1
// run-rustfix
2
2
#![deny(rust_2021_incompatible_closure_captures)]
3
+
//~^ NOTE: the lint level is defined here
3
4
4
5
use std::thread;
5
6
@@ -11,9 +12,12 @@ fn test_send_trait() {
11
12
letmut f = 10;
12
13
let fptr = SendPointer(&mut f as*muti32);
13
14
thread::spawn(move || unsafe{
14
-
//~^ ERROR: `Send` trait implementation
15
+
//~^ ERROR: `Send` trait implementation for closure
16
+
//~| NOTE: in Rust 2018, this closure would implement `Send` as `fptr` implements `Send`, but in Rust 2021, this closure would no longer implement `Send` as `fptr.0` does not implement `Send`
17
+
//~| NOTE: for more information, see
15
18
//~| HELP: add a dummy let to cause `fptr` to be fully captured
16
19
*fptr.0 = 20;
20
+
//~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
17
21
});
18
22
}
19
23
@@ -28,9 +32,12 @@ fn test_sync_trait() {
28
32
let f = CustomInt(&mut f as*muti32);
29
33
let fptr = SyncPointer(f);
30
34
thread::spawn(move || unsafe{
31
-
//~^ ERROR: `Sync`, `Send` trait implementation
35
+
//~^ ERROR: `Sync`, `Send` trait implementation for closure
36
+
//~| NOTE: in Rust 2018, this closure would implement `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure would no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
37
+
//~| NOTE: for more information, see
32
38
//~| HELP: add a dummy let to cause `fptr` to be fully captured
33
39
*fptr.0.0 = 20;
40
+
//~^ NOTE: in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
34
41
});
35
42
}
36
43
@@ -49,16 +56,20 @@ impl Clone for U {
49
56
fntest_clone_trait(){
50
57
let f = U(S(String::from("Hello World")),T(0));
51
58
let c = || {
52
-
//~^ ERROR: `Clone` trait implementation, and drop order
59
+
//~^ ERROR: `Clone` trait implementation for closure and drop order
60
+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f.1` does not implement `Clone`
61
+
//~| NOTE: for more information, see
53
62
//~| HELP: add a dummy let to cause `f` to be fully captured
54
63
let f_1 = f.1;
64
+
//~^ NOTE: in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
55
65
println!("{:?}", f_1.0);
56
66
};
57
67
58
68
let c_clone = c.clone();
59
69
60
70
c_clone();
61
71
}
72
+
//~^ NOTE: in Rust 2018, `f` would be dropped here, but in Rust 2021, only `f.1` would be dropped here alongside the closure
error: `Send` trait implementation will change in Rust 2021
2
-
--> $DIR/auto_traits.rs:13:19
1
+
error: changes to closure capture in Rust 2021 will affect `Send` trait implementation for closure
2
+
--> $DIR/auto_traits.rs:14:19
3
3
|
4
-
LL | thread::spawn(move || unsafe {
5
-
| ___________________^
6
-
LL | |
7
-
LL | |
8
-
LL | | *fptr.0 = 20;
9
-
LL | | });
10
-
| |_____^
4
+
LL | thread::spawn(move || unsafe {
5
+
| ^^^^^^^^^^^^^^ in Rust 2018, this closure would implement `Send` as `fptr` implements `Send`, but in Rust 2021, this closure would no longer implement `Send` as `fptr.0` does not implement `Send`
6
+
...
7
+
LL | *fptr.0 = 20;
8
+
| ------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0`
11
9
|
12
10
note: the lint level is defined here
13
11
--> $DIR/auto_traits.rs:2:9
@@ -20,53 +18,53 @@ help: add a dummy let to cause `fptr` to be fully captured
error: `Sync`, `Send` trait implementation will change in Rust 2021
28
-
--> $DIR/auto_traits.rs:30:19
26
+
error: changes to closure capture in Rust 2021 will affect `Sync`, `Send` trait implementation for closure
27
+
--> $DIR/auto_traits.rs:34:19
29
28
|
30
-
LL | thread::spawn(move || unsafe {
31
-
| ___________________^
32
-
LL | |
33
-
LL | |
34
-
LL | | *fptr.0.0 = 20;
35
-
LL | | });
36
-
| |_____^
29
+
LL | thread::spawn(move || unsafe {
30
+
| ^^^^^^^^^^^^^^ in Rust 2018, this closure would implement `Sync`, `Send` as `fptr` implements `Sync`, `Send`, but in Rust 2021, this closure would no longer implement `Sync`, `Send` as `fptr.0.0` does not implement `Sync`, `Send`
31
+
...
32
+
LL | *fptr.0.0 = 20;
33
+
| --------- in Rust 2018, closure captures all of `fptr`, but in Rust 2021, it only captures `fptr.0.0`
37
34
|
38
35
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
39
36
help: add a dummy let to cause `fptr` to be fully captured
error: `Clone` trait implementation, and drop order will change in Rust 2021
49
-
--> $DIR/auto_traits.rs:51:13
46
+
error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
47
+
--> $DIR/auto_traits.rs:58:13
50
48
|
51
-
LL | let c = || {
52
-
| _____________^
53
-
LL | |
54
-
LL | |
55
-
LL | | let f_1 = f.1;
56
-
LL | | println!("{:?}", f_1.0);
57
-
LL | | };
58
-
| |_____^
49
+
LL | let c = || {
50
+
| ^^ in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f.1` does not implement `Clone`
51
+
...
52
+
LL | let f_1 = f.1;
53
+
| --- in Rust 2018, closure captures all of `f`, but in Rust 2021, it only captures `f.1`
54
+
...
55
+
LL | }
56
+
| - in Rust 2018, `f` would be dropped here, but in Rust 2021, only `f.1` would be dropped here alongside the closure
59
57
|
60
58
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
61
59
help: add a dummy let to cause `f` to be fully captured
0 commit comments