Update tests
This commit is contained in:
parent
099a34cd95
commit
1c989880a1
20 changed files with 227 additions and 557 deletions
|
@ -4,6 +4,14 @@
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Foo(i32);
|
||||||
|
impl Drop for Foo {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("{:?} dropped", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Test Send Trait Migration */
|
/* Test Send Trait Migration */
|
||||||
struct SendPointer(*mut i32);
|
struct SendPointer(*mut i32);
|
||||||
unsafe impl Send for SendPointer {}
|
unsafe impl Send for SendPointer {}
|
||||||
|
@ -42,19 +50,19 @@ fn test_sync_trait() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test Clone Trait Migration */
|
/* Test Clone Trait Migration */
|
||||||
struct S(String);
|
struct S(Foo);
|
||||||
struct T(i32);
|
struct T(i32);
|
||||||
|
|
||||||
struct U(S, T);
|
struct U(S, T);
|
||||||
|
|
||||||
impl Clone for U {
|
impl Clone for U {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
U(S(String::from("Hello World")), T(0))
|
U(S(Foo(0)), T(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_clone_trait() {
|
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 c = || {
|
||||||
let _ = &f;
|
let _ = &f;
|
||||||
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
||||||
|
|
|
@ -4,6 +4,14 @@
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Foo(i32);
|
||||||
|
impl Drop for Foo {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("{:?} dropped", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Test Send Trait Migration */
|
/* Test Send Trait Migration */
|
||||||
struct SendPointer(*mut i32);
|
struct SendPointer(*mut i32);
|
||||||
unsafe impl Send for SendPointer {}
|
unsafe impl Send for SendPointer {}
|
||||||
|
@ -42,19 +50,19 @@ fn test_sync_trait() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test Clone Trait Migration */
|
/* Test Clone Trait Migration */
|
||||||
struct S(String);
|
struct S(Foo);
|
||||||
struct T(i32);
|
struct T(i32);
|
||||||
|
|
||||||
struct U(S, T);
|
struct U(S, T);
|
||||||
|
|
||||||
impl Clone for U {
|
impl Clone for U {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
U(S(String::from("Hello World")), T(0))
|
U(S(Foo(0)), T(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_clone_trait() {
|
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 c = || {
|
||||||
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
//~^ 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`
|
//~| 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`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: changes to closure capture in Rust 2021 will affect `Send` trait implementation for closure
|
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 {
|
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`
|
| ^^^^^^^^^^^^^^ 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
|
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 {
|
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`
|
| ^^^^^^^^^^^^^^ 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
|
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 = || {
|
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`
|
| ^^ 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`
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
#![warn(rust_2021_compatibility)]
|
#![warn(rust_2021_compatibility)]
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Foo(i32);
|
||||||
|
impl Drop for Foo {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("{:?} dropped", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
(@ $body:expr) => {{
|
(@ $body:expr) => {{
|
||||||
let f = || $body;
|
let f = || $body;
|
||||||
|
@ -15,11 +23,11 @@ macro_rules! m {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = (1.to_string(), 2.to_string());
|
let a = (Foo(0), Foo(1));
|
||||||
m!({
|
m!({
|
||||||
let _ = &a;
|
let _ = &a;
|
||||||
//~^ HELP: add a dummy
|
//~^ HELP: add a dummy
|
||||||
let x = a.0;
|
let x = a.0;
|
||||||
println!("{}", x);
|
println!("{:?}", x);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
#![warn(rust_2021_compatibility)]
|
#![warn(rust_2021_compatibility)]
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Foo(i32);
|
||||||
|
impl Drop for Foo {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("{:?} dropped", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
(@ $body:expr) => {{
|
(@ $body:expr) => {{
|
||||||
let f = || $body;
|
let f = || $body;
|
||||||
|
@ -15,10 +23,10 @@ macro_rules! m {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = (1.to_string(), 2.to_string());
|
let a = (Foo(0), Foo(1));
|
||||||
m!({
|
m!({
|
||||||
//~^ HELP: add a dummy
|
//~^ HELP: add a dummy
|
||||||
let x = a.0;
|
let x = a.0;
|
||||||
println!("{}", x);
|
println!("{:?}", x);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: changes to closure capture in Rust 2021 will affect drop order
|
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;
|
LL | let f = || $body;
|
||||||
| _________________^
|
| _________________^
|
||||||
|
@ -15,7 +15,7 @@ LL | / m!({
|
||||||
LL | |
|
LL | |
|
||||||
LL | | let x = a.0;
|
LL | | let x = a.0;
|
||||||
| | --- in Rust 2018, this closure captures all of `a`, but in Rust 2021, it will only capture `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 | | });
|
LL | | });
|
||||||
| |_______- in this macro invocation
|
| |_______- in this macro invocation
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,169 +1,42 @@
|
||||||
|
// run-pass
|
||||||
// run-rustfix
|
// run-rustfix
|
||||||
|
|
||||||
#![deny(rust_2021_incompatible_closure_captures)]
|
#![deny(rust_2021_incompatible_closure_captures)]
|
||||||
//~^ NOTE: the lint level is defined here
|
#![allow(unused)]
|
||||||
|
|
||||||
|
#![feature(once_cell)]
|
||||||
|
|
||||||
// Test cases for types that implement an insignificant drop (stlib defined)
|
// Test cases for types that implement an insignificant drop (stlib defined)
|
||||||
|
|
||||||
// `t` needs Drop because one of its elements needs drop,
|
macro_rules! test_insig_dtor_for_type {
|
||||||
// therefore precise capture might affect drop ordering
|
($t: ty, $disambiguator: ident) => {
|
||||||
fn test1_all_need_migration() {
|
mod $disambiguator {
|
||||||
let t = (String::new(), String::new());
|
use std::collections::*;
|
||||||
let t1 = (String::new(), String::new());
|
use std::lazy::SyncOnceCell;
|
||||||
let t2 = (String::new(), String::new());
|
use std::rc::Rc;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
let c = || {
|
fn _test_for_type(t: $t) {
|
||||||
let _ = (&t, &t1, &t2);
|
let tup = (Mutex::new(0), t);
|
||||||
//~^ 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;
|
let _c = || tup.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.
|
test_insig_dtor_for_type!(i32, prim_i32);
|
||||||
// But in this test cases, `t2` is completely captured and when it is dropped won't be affected
|
test_insig_dtor_for_type!(Vec<i32>, vec_i32);
|
||||||
fn test2_only_precise_paths_need_migration() {
|
test_insig_dtor_for_type!(String, string);
|
||||||
let t = (String::new(), String::new());
|
test_insig_dtor_for_type!(Vec<String>, vec_string);
|
||||||
let t1 = (String::new(), String::new());
|
//test_insig_dtor_for_type!(HashMap<String, String>, hash_map);
|
||||||
let t2 = (String::new(), String::new());
|
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);
|
||||||
|
|
||||||
let c = || {
|
fn main() {}
|
||||||
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());
|
|
||||||
|
|
||||||
// `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`
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
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`
|
|
||||||
};
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,162 +1,42 @@
|
||||||
|
// run-pass
|
||||||
// run-rustfix
|
// run-rustfix
|
||||||
|
|
||||||
#![deny(rust_2021_incompatible_closure_captures)]
|
#![deny(rust_2021_incompatible_closure_captures)]
|
||||||
//~^ NOTE: the lint level is defined here
|
#![allow(unused)]
|
||||||
|
|
||||||
|
#![feature(once_cell)]
|
||||||
|
|
||||||
// Test cases for types that implement an insignificant drop (stlib defined)
|
// Test cases for types that implement an insignificant drop (stlib defined)
|
||||||
|
|
||||||
// `t` needs Drop because one of its elements needs drop,
|
macro_rules! test_insig_dtor_for_type {
|
||||||
// therefore precise capture might affect drop ordering
|
($t: ty, $disambiguator: ident) => {
|
||||||
fn test1_all_need_migration() {
|
mod $disambiguator {
|
||||||
let t = (String::new(), String::new());
|
use std::collections::*;
|
||||||
let t1 = (String::new(), String::new());
|
use std::lazy::SyncOnceCell;
|
||||||
let t2 = (String::new(), String::new());
|
use std::rc::Rc;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
let c = || {
|
fn _test_for_type(t: $t) {
|
||||||
//~^ ERROR: drop order
|
let tup = (Mutex::new(0), t);
|
||||||
//~| NOTE: for more information, see
|
|
||||||
//~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
|
|
||||||
|
|
||||||
let _t = t.0;
|
let _c = || tup.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.
|
test_insig_dtor_for_type!(i32, prim_i32);
|
||||||
// But in this test cases, `t2` is completely captured and when it is dropped won't be affected
|
test_insig_dtor_for_type!(Vec<i32>, vec_i32);
|
||||||
fn test2_only_precise_paths_need_migration() {
|
test_insig_dtor_for_type!(String, string);
|
||||||
let t = (String::new(), String::new());
|
test_insig_dtor_for_type!(Vec<String>, vec_string);
|
||||||
let t1 = (String::new(), String::new());
|
//test_insig_dtor_for_type!(HashMap<String, String>, hash_map);
|
||||||
let t2 = (String::new(), String::new());
|
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);
|
||||||
|
|
||||||
let c = || {
|
fn main() {}
|
||||||
//~^ 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());
|
|
||||||
|
|
||||||
// `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`
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
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`
|
|
||||||
};
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
struct InsignificantDropPoint {
|
struct InsignificantDropPoint {
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: Mutex<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for InsignificantDropPoint {
|
impl Drop for InsignificantDropPoint {
|
||||||
|
@ -15,7 +17,7 @@ impl Drop for InsignificantDropPoint {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SigDrop;
|
struct SigDrop { x: () }
|
||||||
|
|
||||||
impl Drop for SigDrop {
|
impl Drop for SigDrop {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
|
@ -30,12 +32,22 @@ impl<T> Drop for GenericStruct<T> {
|
||||||
fn drop(&mut self) {}
|
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.
|
// `SigDrop` implements drop and therefore needs to be migrated.
|
||||||
fn significant_drop_needs_migration() {
|
fn significant_drop_needs_migration() {
|
||||||
let t = (SigDrop {}, SigDrop {});
|
let t = (SigDrop { x: () }, SigDrop { x: () });
|
||||||
|
|
||||||
let c = || {
|
let c = || {
|
||||||
let _ = &t;
|
|
||||||
//~^ ERROR: drop order
|
//~^ ERROR: drop order
|
||||||
//~| NOTE: for more information, see
|
//~| NOTE: for more information, see
|
||||||
//~| HELP: add a dummy let to cause `t` to be fully captured
|
//~| 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
|
// consdered to have an significant drop. Since the elements
|
||||||
// of `GenericStruct` implement drop, migration is required.
|
// of `GenericStruct` implement drop, migration is required.
|
||||||
fn generic_struct_with_significant_drop_needs_migration() {
|
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
|
// move is used to force i32 to be copied instead of being a ref
|
||||||
let c = move || {
|
let c = move || {
|
||||||
let _ = &t;
|
|
||||||
//~^ ERROR: drop order
|
//~^ ERROR: drop order
|
||||||
//~| NOTE: for more information, see
|
//~| NOTE: for more information, see
|
||||||
//~| HELP: add a dummy let to cause `t` to be fully captured
|
//~| HELP: add a dummy let to cause `t` to be fully captured
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
struct InsignificantDropPoint {
|
struct InsignificantDropPoint {
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: Mutex<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for InsignificantDropPoint {
|
impl Drop for InsignificantDropPoint {
|
||||||
|
@ -30,6 +32,17 @@ impl<T> Drop for GenericStruct<T> {
|
||||||
fn drop(&mut self) {}
|
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.
|
// `SigDrop` implements drop and therefore needs to be migrated.
|
||||||
fn significant_drop_needs_migration() {
|
fn significant_drop_needs_migration() {
|
||||||
let t = (SigDrop {}, SigDrop {});
|
let t = (SigDrop {}, SigDrop {});
|
||||||
|
|
|
@ -1,45 +1,19 @@
|
||||||
error: changes to closure capture in Rust 2021 will affect drop order
|
error[E0107]: missing generics for struct `Mutex`
|
||||||
--> $DIR/insignificant_drop_attr_migrations.rs:37:13
|
--> $DIR/insignificant_drop_attr_migrations.rs:12:8
|
||||||
|
|
|
|
||||||
LL | let c = || {
|
LL | y: Mutex,
|
||||||
| ^^
|
| ^^^^^ expected 1 generic argument
|
||||||
...
|
|
||||||
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: the lint level is defined here
|
note: struct defined here, with 1 generic parameter: `T`
|
||||||
--> $DIR/insignificant_drop_attr_migrations.rs:3:9
|
--> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | #![deny(rust_2021_incompatible_closure_captures)]
|
LL | pub struct Mutex<T: ?Sized> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^ -
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
|
help: add missing generic argument
|
||||||
help: add a dummy let to cause `t` to be fully captured
|
|
||||||
|
|
|
||||||
LL ~ let c = || {
|
|
||||||
LL + let _ = &t;
|
|
||||||
|
|
|
|
||||||
|
LL | y: Mutex<T>,
|
||||||
|
| ~~~~~~~~
|
||||||
|
|
||||||
error: changes to closure capture in Rust 2021 will affect drop order
|
error: aborting due to previous error
|
||||||
--> $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;
|
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0107`.
|
||||||
|
|
|
@ -5,8 +5,17 @@
|
||||||
#![deny(rust_2021_incompatible_closure_captures)]
|
#![deny(rust_2021_incompatible_closure_captures)]
|
||||||
//~^ NOTE: the lint level is defined here
|
//~^ 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() {
|
fn main() {
|
||||||
let a = ("hey".to_string(), "123".to_string());
|
let a = (Foo(0), Foo(1));
|
||||||
let _ = || { let _ = &a; dbg!(a.0) };
|
let _ = || { let _ = &a; dbg!(a.0) };
|
||||||
//~^ ERROR: drop order
|
//~^ ERROR: drop order
|
||||||
//~| NOTE: will only capture `a.0`
|
//~| NOTE: will only capture `a.0`
|
||||||
|
|
|
@ -5,8 +5,17 @@
|
||||||
#![deny(rust_2021_incompatible_closure_captures)]
|
#![deny(rust_2021_incompatible_closure_captures)]
|
||||||
//~^ NOTE: the lint level is defined here
|
//~^ 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() {
|
fn main() {
|
||||||
let a = ("hey".to_string(), "123".to_string());
|
let a = (Foo(0), Foo(1));
|
||||||
let _ = || dbg!(a.0);
|
let _ = || dbg!(a.0);
|
||||||
//~^ ERROR: drop order
|
//~^ ERROR: drop order
|
||||||
//~| NOTE: will only capture `a.0`
|
//~| NOTE: will only capture `a.0`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: changes to closure capture in Rust 2021 will affect drop order
|
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);
|
LL | let _ = || dbg!(a.0);
|
||||||
| ^^^^^^^^---^
|
| ^^^^^^^^---^
|
||||||
|
|
|
@ -4,7 +4,22 @@
|
||||||
|
|
||||||
use std::thread;
|
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)]
|
#[derive(Clone)]
|
||||||
struct T(i32);
|
struct T(i32);
|
||||||
|
@ -13,13 +28,13 @@ struct U(S, T);
|
||||||
|
|
||||||
impl Clone for U {
|
impl Clone for U {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
U(S(String::from("Hello World")), T(0))
|
U(S(Foo::from("Hello World")), T(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_multi_issues() {
|
fn test_multi_issues() {
|
||||||
let f1 = U(S(String::from("foo")), T(0));
|
let f1 = U(S(Foo::from("foo")), T(0));
|
||||||
let f2 = U(S(String::from("bar")), T(0));
|
let f2 = U(S(Foo::from("bar")), T(0));
|
||||||
let c = || {
|
let c = || {
|
||||||
let _ = (&f1, &f2);
|
let _ = (&f1, &f2);
|
||||||
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
//~^ 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
|
//~^ 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() {
|
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 c = || {
|
||||||
let _ = &f1;
|
let _ = &f1;
|
||||||
//~^ ERROR: `Clone` trait implementation for closure
|
//~^ ERROR: `Clone` trait implementation for closure
|
||||||
|
@ -60,12 +75,12 @@ struct U1(S, T, S);
|
||||||
|
|
||||||
impl Clone for U1 {
|
impl Clone for U1 {
|
||||||
fn clone(&self) -> Self {
|
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() {
|
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 c = || {
|
||||||
let _ = &f1;
|
let _ = &f1;
|
||||||
//~^ ERROR: `Clone` trait implementation for closure
|
//~^ 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() {
|
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 c = || {
|
||||||
let _ = &f1;
|
let _ = &f1;
|
||||||
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
||||||
|
|
|
@ -4,7 +4,22 @@
|
||||||
|
|
||||||
use std::thread;
|
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)]
|
#[derive(Clone)]
|
||||||
struct T(i32);
|
struct T(i32);
|
||||||
|
@ -13,13 +28,13 @@ struct U(S, T);
|
||||||
|
|
||||||
impl Clone for U {
|
impl Clone for U {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
U(S(String::from("Hello World")), T(0))
|
U(S(Foo::from("Hello World")), T(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_multi_issues() {
|
fn test_multi_issues() {
|
||||||
let f1 = U(S(String::from("foo")), T(0));
|
let f1 = U(S(Foo::from("foo")), T(0));
|
||||||
let f2 = U(S(String::from("bar")), T(0));
|
let f2 = U(S(Foo::from("bar")), T(0));
|
||||||
let c = || {
|
let c = || {
|
||||||
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
//~^ 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`
|
//~| 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
|
//~^ 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() {
|
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 c = || {
|
||||||
//~^ ERROR: `Clone` trait implementation for closure
|
//~^ 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`
|
//~| 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 {
|
impl Clone for U1 {
|
||||||
fn clone(&self) -> Self {
|
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() {
|
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 c = || {
|
||||||
//~^ ERROR: `Clone` trait implementation for closure
|
//~^ 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`
|
//~| 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() {
|
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 c = || {
|
||||||
//~^ ERROR: `Clone` trait implementation for closure and drop order
|
//~^ 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`
|
//~| 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`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: changes to closure capture in Rust 2021 will affect `Clone` trait implementation for closure and drop order
|
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 = || {
|
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`
|
| ^^ 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
|
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 = || {
|
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`
|
| ^^ 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
|
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 = || {
|
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
|
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 = || {
|
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`
|
| ^^ 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
|
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 {
|
LL | thread::spawn(move || unsafe {
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -165,7 +165,7 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
|
||||||
fn test8_drop_order_and_blocks() {
|
fn test8_drop_order_and_blocks() {
|
||||||
{
|
{
|
||||||
let tuple =
|
let tuple =
|
||||||
(String::from("foo"), String::from("bar"));
|
(Foo(0), Foo(1));
|
||||||
{
|
{
|
||||||
let c = || {
|
let c = || {
|
||||||
let _ = &tuple;
|
let _ = &tuple;
|
||||||
|
@ -184,7 +184,7 @@ fn test8_drop_order_and_blocks() {
|
||||||
|
|
||||||
fn test9_drop_order_and_nested_closures() {
|
fn test9_drop_order_and_nested_closures() {
|
||||||
let tuple =
|
let tuple =
|
||||||
(String::from("foo"), String::from("bar"));
|
(Foo(0), Foo(1));
|
||||||
let b = || {
|
let b = || {
|
||||||
let c = || {
|
let c = || {
|
||||||
let _ = &tuple;
|
let _ = &tuple;
|
||||||
|
|
|
@ -158,7 +158,7 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
|
||||||
fn test8_drop_order_and_blocks() {
|
fn test8_drop_order_and_blocks() {
|
||||||
{
|
{
|
||||||
let tuple =
|
let tuple =
|
||||||
(String::from("foo"), String::from("bar"));
|
(Foo(0), Foo(1));
|
||||||
{
|
{
|
||||||
let c = || {
|
let c = || {
|
||||||
//~^ ERROR: drop order
|
//~^ ERROR: drop order
|
||||||
|
@ -176,7 +176,7 @@ fn test8_drop_order_and_blocks() {
|
||||||
|
|
||||||
fn test9_drop_order_and_nested_closures() {
|
fn test9_drop_order_and_nested_closures() {
|
||||||
let tuple =
|
let tuple =
|
||||||
(String::from("foo"), String::from("bar"));
|
(Foo(0), Foo(1));
|
||||||
let b = || {
|
let b = || {
|
||||||
let c = || {
|
let c = || {
|
||||||
//~^ ERROR: drop order
|
//~^ ERROR: drop order
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue