Skip to content

Commit ca44372

Browse files
committed
Handle multi diagnostics
1 parent 59f634b commit ca44372

File tree

7 files changed

+624
-184
lines changed

7 files changed

+624
-184
lines changed

compiler/rustc_typeck/src/check/upvar.rs

+176-176
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// run-rustfix
2+
#![deny(rust_2021_incompatible_closure_captures)]
3+
//~^ NOTE: the lint level is defined here
4+
5+
use std::thread;
6+
7+
struct S(String);
8+
9+
#[derive(Clone)]
10+
struct T(i32);
11+
12+
struct U(S, T);
13+
14+
impl Clone for U {
15+
fn clone(&self) -> Self {
16+
U(S(String::from("Hello World")), T(0))
17+
}
18+
}
19+
20+
fn test_multi_issues() {
21+
let f1 = U(S(String::from("foo")), T(0));
22+
let f2 = U(S(String::from("bar")), T(0));
23+
let c = || { let _ = (&f1, &f2);
24+
//~^ ERROR: `Clone` trait implementation for closure, and drop order
25+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
26+
//~| NOTE: for more information, see
27+
//~| HELP: add a dummy let to cause `f1`, `f2` to be fully captured
28+
let _f_1 = f1.0;
29+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
30+
let _f_2 = f2.1;
31+
//~^ NOTE: in Rust 2018, closure captures all of `f2`, but in Rust 2021, it only captures `f2.1`
32+
};
33+
34+
let c_clone = c.clone();
35+
36+
c_clone();
37+
}
38+
//~^ NOTE: in Rust 2018, `f2` would be dropped here, but in Rust 2021, only `f2.1` would be dropped here alongside the closure
39+
40+
fn test_capturing_all_disjoint_fields_individually() {
41+
let f1 = U(S(String::from("foo")), T(0));
42+
let c = || { let _ = &f1;
43+
//~^ ERROR: `Clone` trait implementation for closure
44+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
45+
//~| NOTE: for more information, see
46+
//~| HELP: add a dummy let to cause `f1` to be fully captured
47+
let _f_1 = f1.0;
48+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
49+
let _f_2 = f1.1;
50+
};
51+
52+
let c_clone = c.clone();
53+
54+
c_clone();
55+
}
56+
57+
struct U1(S, T, S);
58+
59+
impl Clone for U1 {
60+
fn clone(&self) -> Self {
61+
U1(S(String::from("foo")), T(0), S(String::from("bar")))
62+
}
63+
}
64+
65+
fn test_capturing_several_disjoint_fields_individually_1() {
66+
let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
67+
let c = || { let _ = &f1;
68+
//~^ ERROR: `Clone` trait implementation for closure
69+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
70+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.2` does not implement `Clone`
71+
//~| NOTE: for more information, see
72+
//~| HELP: add a dummy let to cause `f1` to be fully captured
73+
let _f_0 = f1.0;
74+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
75+
let _f_2 = f1.2;
76+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.2`
77+
};
78+
79+
let c_clone = c.clone();
80+
81+
c_clone();
82+
}
83+
84+
fn test_capturing_several_disjoint_fields_individually_2() {
85+
let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
86+
let c = || { let _ = &f1;
87+
//~^ ERROR: `Clone` trait implementation for closure, and drop order
88+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
89+
//~| NOTE: for more information, see
90+
//~| HELP: add a dummy let to cause `f1` to be fully captured
91+
let _f_0 = f1.0;
92+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
93+
let _f_1 = f1.1;
94+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.1`
95+
};
96+
97+
let c_clone = c.clone();
98+
99+
c_clone();
100+
}
101+
//~^ NOTE: in Rust 2018, `f1` would be dropped here, but in Rust 2021, only `f1.1` would be dropped here alongside the closure
102+
//~| NOTE: in Rust 2018, `f1` would be dropped here, but in Rust 2021, only `f1.0` would be dropped here alongside the closure
103+
104+
struct SendPointer(*mut i32);
105+
unsafe impl Send for SendPointer {}
106+
107+
struct CustomInt(*mut i32);
108+
struct SyncPointer(CustomInt);
109+
unsafe impl Sync for SyncPointer {}
110+
unsafe impl Send for CustomInt {}
111+
112+
fn test_multi_traits_issues() {
113+
let mut f1 = 10;
114+
let f1 = CustomInt(&mut f1 as *mut i32);
115+
let fptr1 = SyncPointer(f1);
116+
117+
let mut f2 = 10;
118+
let fptr2 = SendPointer(&mut f2 as *mut i32);
119+
thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe {
120+
//~^ ERROR: `Sync`, `Send` trait implementation for closure
121+
//~| NOTE: in Rust 2018, this closure would implement `Sync`, `Send` as `fptr1` implements `Sync`, `Send`, but in Rust 2021, this closure would no longer implement `Sync`, `Send` as `fptr1.0.0` does not implement `Sync`, `Send`
122+
//~| NOTE: in Rust 2018, this closure would implement `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure would no longer implement `Send` as `fptr2.0` does not implement `Send`
123+
//~| NOTE: for more information, see
124+
//~| HELP: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
125+
*fptr1.0.0 = 20;
126+
//~^ NOTE: in Rust 2018, closure captures all of `fptr1`, but in Rust 2021, it only captures `fptr1.0.0`
127+
*fptr2.0 = 20;
128+
//~^ NOTE: in Rust 2018, closure captures all of `fptr2`, but in Rust 2021, it only captures `fptr2.0`
129+
} });
130+
}
131+
132+
fn main() {
133+
test_multi_issues();
134+
test_capturing_all_disjoint_fields_individually();
135+
test_capturing_several_disjoint_fields_individually_1();
136+
test_capturing_several_disjoint_fields_individually_2();
137+
test_multi_traits_issues();
138+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// run-rustfix
2+
#![deny(rust_2021_incompatible_closure_captures)]
3+
//~^ NOTE: the lint level is defined here
4+
5+
use std::thread;
6+
7+
struct S(String);
8+
9+
#[derive(Clone)]
10+
struct T(i32);
11+
12+
struct U(S, T);
13+
14+
impl Clone for U {
15+
fn clone(&self) -> Self {
16+
U(S(String::from("Hello World")), T(0))
17+
}
18+
}
19+
20+
fn test_multi_issues() {
21+
let f1 = U(S(String::from("foo")), T(0));
22+
let f2 = U(S(String::from("bar")), T(0));
23+
let c = || {
24+
//~^ ERROR: `Clone` trait implementation for closure, and drop order
25+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
26+
//~| NOTE: for more information, see
27+
//~| HELP: add a dummy let to cause `f1`, `f2` to be fully captured
28+
let _f_1 = f1.0;
29+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
30+
let _f_2 = f2.1;
31+
//~^ NOTE: in Rust 2018, closure captures all of `f2`, but in Rust 2021, it only captures `f2.1`
32+
};
33+
34+
let c_clone = c.clone();
35+
36+
c_clone();
37+
}
38+
//~^ NOTE: in Rust 2018, `f2` would be dropped here, but in Rust 2021, only `f2.1` would be dropped here alongside the closure
39+
40+
fn test_capturing_all_disjoint_fields_individually() {
41+
let f1 = U(S(String::from("foo")), T(0));
42+
let c = || {
43+
//~^ ERROR: `Clone` trait implementation for closure
44+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
45+
//~| NOTE: for more information, see
46+
//~| HELP: add a dummy let to cause `f1` to be fully captured
47+
let _f_1 = f1.0;
48+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
49+
let _f_2 = f1.1;
50+
};
51+
52+
let c_clone = c.clone();
53+
54+
c_clone();
55+
}
56+
57+
struct U1(S, T, S);
58+
59+
impl Clone for U1 {
60+
fn clone(&self) -> Self {
61+
U1(S(String::from("foo")), T(0), S(String::from("bar")))
62+
}
63+
}
64+
65+
fn test_capturing_several_disjoint_fields_individually_1() {
66+
let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
67+
let c = || {
68+
//~^ ERROR: `Clone` trait implementation for closure
69+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
70+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.2` does not implement `Clone`
71+
//~| NOTE: for more information, see
72+
//~| HELP: add a dummy let to cause `f1` to be fully captured
73+
let _f_0 = f1.0;
74+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
75+
let _f_2 = f1.2;
76+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.2`
77+
};
78+
79+
let c_clone = c.clone();
80+
81+
c_clone();
82+
}
83+
84+
fn test_capturing_several_disjoint_fields_individually_2() {
85+
let f1 = U1(S(String::from("foo")), T(0), S(String::from("bar")));
86+
let c = || {
87+
//~^ ERROR: `Clone` trait implementation for closure, and drop order
88+
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f1` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f1.0` does not implement `Clone`
89+
//~| NOTE: for more information, see
90+
//~| HELP: add a dummy let to cause `f1` to be fully captured
91+
let _f_0 = f1.0;
92+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.0`
93+
let _f_1 = f1.1;
94+
//~^ NOTE: in Rust 2018, closure captures all of `f1`, but in Rust 2021, it only captures `f1.1`
95+
};
96+
97+
let c_clone = c.clone();
98+
99+
c_clone();
100+
}
101+
//~^ NOTE: in Rust 2018, `f1` would be dropped here, but in Rust 2021, only `f1.1` would be dropped here alongside the closure
102+
//~| NOTE: in Rust 2018, `f1` would be dropped here, but in Rust 2021, only `f1.0` would be dropped here alongside the closure
103+
104+
struct SendPointer(*mut i32);
105+
unsafe impl Send for SendPointer {}
106+
107+
struct CustomInt(*mut i32);
108+
struct SyncPointer(CustomInt);
109+
unsafe impl Sync for SyncPointer {}
110+
unsafe impl Send for CustomInt {}
111+
112+
fn test_multi_traits_issues() {
113+
let mut f1 = 10;
114+
let f1 = CustomInt(&mut f1 as *mut i32);
115+
let fptr1 = SyncPointer(f1);
116+
117+
let mut f2 = 10;
118+
let fptr2 = SendPointer(&mut f2 as *mut i32);
119+
thread::spawn(move || unsafe {
120+
//~^ ERROR: `Sync`, `Send` trait implementation for closure
121+
//~| NOTE: in Rust 2018, this closure would implement `Sync`, `Send` as `fptr1` implements `Sync`, `Send`, but in Rust 2021, this closure would no longer implement `Sync`, `Send` as `fptr1.0.0` does not implement `Sync`, `Send`
122+
//~| NOTE: in Rust 2018, this closure would implement `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure would no longer implement `Send` as `fptr2.0` does not implement `Send`
123+
//~| NOTE: for more information, see
124+
//~| HELP: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
125+
*fptr1.0.0 = 20;
126+
//~^ NOTE: in Rust 2018, closure captures all of `fptr1`, but in Rust 2021, it only captures `fptr1.0.0`
127+
*fptr2.0 = 20;
128+
//~^ NOTE: in Rust 2018, closure captures all of `fptr2`, but in Rust 2021, it only captures `fptr2.0`
129+
});
130+
}
131+
132+
fn main() {
133+
test_multi_issues();
134+
test_capturing_all_disjoint_fields_individually();
135+
test_capturing_several_disjoint_fields_individually_1();
136+
test_capturing_several_disjoint_fields_individually_2();
137+
test_multi_traits_issues();
138+
}

0 commit comments

Comments
 (0)