Test cases for RFC 2229
This commit is contained in:
parent
237ad12698
commit
01df56343b
28 changed files with 914 additions and 0 deletions
|
@ -0,0 +1,86 @@
|
|||
// Test that arrays are completely captured by closures by relying on the borrow check diagnostics
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
fn arrays_1() {
|
||||
let mut arr = [1, 2, 3, 4, 5];
|
||||
|
||||
let mut c = || {
|
||||
arr[0] += 10;
|
||||
};
|
||||
|
||||
// c will capture `arr` completely, therefore another index into the
|
||||
// array can't be modified here
|
||||
arr[1] += 10;
|
||||
//~^ ERROR: cannot use `arr` because it was mutably borrowed
|
||||
//~| ERROR: cannot use `arr[_]` because it was mutably borrowed
|
||||
c();
|
||||
}
|
||||
|
||||
fn arrays_2() {
|
||||
let mut arr = [1, 2, 3, 4, 5];
|
||||
|
||||
let c = || {
|
||||
println!("{:#?}", &arr[3..4]);
|
||||
};
|
||||
|
||||
// c will capture `arr` completely, therefore another index into the
|
||||
// array can't be modified here
|
||||
arr[1] += 10;
|
||||
//~^ ERROR: cannot assign to `arr[_]` because it is borrowed
|
||||
c();
|
||||
}
|
||||
|
||||
fn arrays_3() {
|
||||
let mut arr = [1, 2, 3, 4, 5];
|
||||
|
||||
let c = || {
|
||||
println!("{}", arr[3]);
|
||||
};
|
||||
|
||||
// c will capture `arr` completely, therefore another index into the
|
||||
// array can't be modified here
|
||||
arr[1] += 10;
|
||||
//~^ ERROR: cannot assign to `arr[_]` because it is borrowed
|
||||
c();
|
||||
}
|
||||
|
||||
fn arrays_4() {
|
||||
let mut arr = [1, 2, 3, 4, 5];
|
||||
|
||||
let mut c = || {
|
||||
arr[1] += 10;
|
||||
};
|
||||
|
||||
// c will capture `arr` completely, therefore we cannot borrow another index
|
||||
// into the array.
|
||||
println!("{}", arr[3]);
|
||||
//~^ ERROR: cannot use `arr` because it was mutably borrowed
|
||||
//~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn arrays_5() {
|
||||
let mut arr = [1, 2, 3, 4, 5];
|
||||
|
||||
let mut c = || {
|
||||
arr[1] += 10;
|
||||
};
|
||||
|
||||
// c will capture `arr` completely, therefore we cannot borrow other indecies
|
||||
// into the array.
|
||||
println!("{:#?}", &arr[3..2]);
|
||||
//~^ ERROR: cannot borrow `arr` as immutable because it is also borrowed as mutable
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
arrays_1();
|
||||
arrays_2();
|
||||
arrays_3();
|
||||
arrays_4();
|
||||
arrays_5();
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/arrays.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0503]: cannot use `arr` because it was mutably borrowed
|
||||
--> $DIR/arrays.rs:15:5
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- borrow of `arr` occurs here
|
||||
LL | arr[0] += 10;
|
||||
| --- borrow occurs due to use of `arr` in closure
|
||||
...
|
||||
LL | arr[1] += 10;
|
||||
| ^^^^^^ use of borrowed `arr`
|
||||
...
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error[E0503]: cannot use `arr[_]` because it was mutably borrowed
|
||||
--> $DIR/arrays.rs:15:5
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- borrow of `arr` occurs here
|
||||
LL | arr[0] += 10;
|
||||
| --- borrow occurs due to use of `arr` in closure
|
||||
...
|
||||
LL | arr[1] += 10;
|
||||
| ^^^^^^^^^^^^ use of borrowed `arr`
|
||||
...
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error[E0506]: cannot assign to `arr[_]` because it is borrowed
|
||||
--> $DIR/arrays.rs:30:5
|
||||
|
|
||||
LL | let c = || {
|
||||
| -- borrow of `arr[_]` occurs here
|
||||
LL | println!("{:#?}", &arr[3..4]);
|
||||
| --- borrow occurs due to use in closure
|
||||
...
|
||||
LL | arr[1] += 10;
|
||||
| ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error[E0506]: cannot assign to `arr[_]` because it is borrowed
|
||||
--> $DIR/arrays.rs:44:5
|
||||
|
|
||||
LL | let c = || {
|
||||
| -- borrow of `arr[_]` occurs here
|
||||
LL | println!("{}", arr[3]);
|
||||
| --- borrow occurs due to use in closure
|
||||
...
|
||||
LL | arr[1] += 10;
|
||||
| ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error[E0503]: cannot use `arr` because it was mutably borrowed
|
||||
--> $DIR/arrays.rs:58:20
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- borrow of `arr` occurs here
|
||||
LL | arr[1] += 10;
|
||||
| --- borrow occurs due to use of `arr` in closure
|
||||
...
|
||||
LL | println!("{}", arr[3]);
|
||||
| ^^^^^^ use of borrowed `arr`
|
||||
...
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/arrays.rs:58:20
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- mutable borrow occurs here
|
||||
LL | arr[1] += 10;
|
||||
| --- first borrow occurs due to use of `arr` in closure
|
||||
...
|
||||
LL | println!("{}", arr[3]);
|
||||
| ^^^^^^ immutable borrow occurs here
|
||||
...
|
||||
LL | c();
|
||||
| - mutable borrow later used here
|
||||
|
||||
error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/arrays.rs:74:24
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- mutable borrow occurs here
|
||||
LL | arr[1] += 10;
|
||||
| --- first borrow occurs due to use of `arr` in closure
|
||||
...
|
||||
LL | println!("{:#?}", &arr[3..2]);
|
||||
| ^^^ immutable borrow occurs here
|
||||
...
|
||||
LL | c();
|
||||
| - mutable borrow later used here
|
||||
|
||||
error: aborting due to 7 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0502, E0503, E0506.
|
||||
For more information about an error, try `rustc --explain E0502`.
|
|
@ -0,0 +1,65 @@
|
|||
// Test borrow checker when we precise capture when using boxes
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
struct MetaData { x: String, name: String }
|
||||
struct Data { m: MetaData }
|
||||
struct BoxedData(Box<Data>);
|
||||
struct EvenMoreBoxedData(Box<BoxedData>);
|
||||
|
||||
// Check diagnostics when the same path is mutated both inside and outside the closure
|
||||
fn box_1() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let mut e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let mut c = || {
|
||||
e.0.0.m.x = format!("not-x");
|
||||
};
|
||||
|
||||
e.0.0.m.x = format!("not-x");
|
||||
//~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed
|
||||
c();
|
||||
}
|
||||
|
||||
// Check diagnostics when a path is mutated inside a closure while attempting to read it outside
|
||||
// the closure.
|
||||
fn box_2() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let mut e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let mut c = || {
|
||||
e.0.0.m.x = format!("not-x");
|
||||
};
|
||||
|
||||
println!("{}", e.0.0.m.x);
|
||||
//~^ ERROR: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable
|
||||
c();
|
||||
}
|
||||
|
||||
// Check diagnostics when a path is read inside a closure while attempting to mutate it outside
|
||||
// the closure.
|
||||
fn box_3() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let mut e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let c = || {
|
||||
println!("{}", e.0.0.m.x);
|
||||
};
|
||||
|
||||
e.0.0.m.x = format!("not-x");
|
||||
//~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed
|
||||
c();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
box_1();
|
||||
box_2();
|
||||
box_3();
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/box.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
|
||||
--> $DIR/box.rs:22:5
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- borrow of `e.0.0.m.x` occurs here
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| - borrow occurs due to use in closure
|
||||
...
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error[E0502]: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/box.rs:39:20
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- mutable borrow occurs here
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| - first borrow occurs due to use of `e.0.0.m.x` in closure
|
||||
...
|
||||
LL | println!("{}", e.0.0.m.x);
|
||||
| ^^^^^^^^^ immutable borrow occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - mutable borrow later used here
|
||||
|
||||
error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
|
||||
--> $DIR/box.rs:56:5
|
||||
|
|
||||
LL | let c = || {
|
||||
| -- borrow of `e.0.0.m.x` occurs here
|
||||
LL | println!("{}", e.0.0.m.x);
|
||||
| - borrow occurs due to use in closure
|
||||
...
|
||||
LL | e.0.0.m.x = format!("not-x");
|
||||
| ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - borrow later used here
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0502, E0506.
|
||||
For more information about an error, try `rustc --explain E0502`.
|
|
@ -0,0 +1,28 @@
|
|||
// Test that when a borrow checker diagnostics are emitted, it's as precise
|
||||
// as the capture by the closure.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
#![allow(unused)]
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
struct Wrapper {
|
||||
p: Point,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut w = Wrapper { p: Point { x: 10, y: 10 } };
|
||||
|
||||
let mut c = || {
|
||||
w.p.x += 20;
|
||||
};
|
||||
|
||||
let py = &mut w.p.x;
|
||||
//~^ ERROR: cannot borrow `w.p.x` as mutable more than once at a time
|
||||
c();
|
||||
|
||||
*py = 20
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/multilevel-path.rs:4:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0499]: cannot borrow `w.p.x` as mutable more than once at a time
|
||||
--> $DIR/multilevel-path.rs:23:14
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- first mutable borrow occurs here
|
||||
LL | w.p.x += 20;
|
||||
| - first borrow occurs due to use of `w.p.x` in closure
|
||||
...
|
||||
LL | let py = &mut w.p.x;
|
||||
| ^^^^^^^^^^ second mutable borrow occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - first borrow later used here
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0499`.
|
|
@ -0,0 +1,26 @@
|
|||
// Test that borrow checker error is accurate and that min capture pass of the
|
||||
// closure analysis is working as expected.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 10, y: 20 };
|
||||
|
||||
// `p` is captured via mutable borrow.
|
||||
let mut c = || {
|
||||
p.x += 10;
|
||||
println!("{:?}", p);
|
||||
};
|
||||
|
||||
|
||||
println!("{:?}", p);
|
||||
//~^ ERROR: cannot borrow `p` as immutable because it is also borrowed as mutable
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/simple-struct-min-capture.rs:4:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0502]: cannot borrow `p` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/simple-struct-min-capture.rs:23:22
|
||||
|
|
||||
LL | let mut c = || {
|
||||
| -- mutable borrow occurs here
|
||||
LL | p.x += 10;
|
||||
| - first borrow occurs due to use of `p` in closure
|
||||
...
|
||||
LL | println!("{:?}", p);
|
||||
| ^ immutable borrow occurs here
|
||||
LL |
|
||||
LL | c();
|
||||
| - mutable borrow later used here
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
97
src/test/ui/closures/2229_closure_analysis/run_pass/box.rs
Normal file
97
src/test/ui/closures/2229_closure_analysis/run_pass/box.rs
Normal file
|
@ -0,0 +1,97 @@
|
|||
// run-pass
|
||||
|
||||
// Test precise capture when using boxes
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
|
||||
|
||||
struct MetaData { x: String, name: String }
|
||||
struct Data { m: MetaData }
|
||||
struct BoxedData(Box<Data>);
|
||||
struct EvenMoreBoxedData(Box<BoxedData>);
|
||||
|
||||
// Mutate disjoint paths, one inside one outside the closure
|
||||
fn box_1() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let mut e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let mut c = || {
|
||||
e.0.0.m.x = format!("not-x");
|
||||
};
|
||||
|
||||
e.0.0.m.name = format!("not-name");
|
||||
c();
|
||||
}
|
||||
|
||||
// Mutate a path inside the closure and read a disjoint path outside the closure
|
||||
fn box_2() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let mut e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let mut c = || {
|
||||
e.0.0.m.x = format!("not-x");
|
||||
};
|
||||
|
||||
println!("{}", e.0.0.m.name);
|
||||
c();
|
||||
}
|
||||
|
||||
// Read a path inside the closure and mutate a disjoint path outside the closure
|
||||
fn box_3() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let mut e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let c = || {
|
||||
println!("{}", e.0.0.m.name);
|
||||
};
|
||||
|
||||
e.0.0.m.x = format!("not-x");
|
||||
c();
|
||||
}
|
||||
|
||||
// Read disjoint paths, one inside the closure and one outside the closure.
|
||||
fn box_4() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let c = || {
|
||||
println!("{}", e.0.0.m.name);
|
||||
};
|
||||
|
||||
println!("{}", e.0.0.m.x);
|
||||
c();
|
||||
}
|
||||
|
||||
// Read the same path, once inside the closure and once outside the closure.
|
||||
fn box_5() {
|
||||
let m = MetaData { x: format!("x"), name: format!("name") };
|
||||
let d = Data { m };
|
||||
let b = BoxedData(Box::new(d));
|
||||
let e = EvenMoreBoxedData(Box::new(b));
|
||||
|
||||
let c = || {
|
||||
println!("{}", e.0.0.m.name);
|
||||
};
|
||||
|
||||
println!("{}", e.0.0.m.name);
|
||||
c();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
box_1();
|
||||
box_2();
|
||||
box_3();
|
||||
box_4();
|
||||
box_5();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/box.rs:5:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// run-pass
|
||||
|
||||
// Test that we can immutably borrow field of an instance of a structure from within a closure,
|
||||
// while having a mutable borrow to another field of the same instance outside the closure.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 10, y: 10 };
|
||||
|
||||
let c = || {
|
||||
println!("{}", p.x);
|
||||
};
|
||||
|
||||
// `c` should only capture `p.x`, therefore mutating `p.y` is allowed.
|
||||
let py = &mut p.y;
|
||||
|
||||
c();
|
||||
*py = 20;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-disjoint-field-struct.rs:6:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// run-pass
|
||||
|
||||
// Test that we can mutate an element of a tuple from within a closure
|
||||
// while immutably borrowing another element of the same tuple outside the closure.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() {
|
||||
let mut t = (10, 10);
|
||||
|
||||
let mut c = || {
|
||||
let t1 = &mut t.1;
|
||||
*t1 = 20;
|
||||
};
|
||||
|
||||
// Test that `c` only captures t.1, therefore reading t.0 is allowed.
|
||||
println!("{}", t.0);
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-disjoint-field-tuple-mut.rs:6:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
|
||||
// Test that we can immutably borrow an element of a tuple from within a closure,
|
||||
// while having a mutable borrow to another element of the same tuple outside the closure.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() {
|
||||
let mut t = (10, 10);
|
||||
|
||||
let c = || {
|
||||
println!("{}", t.0);
|
||||
};
|
||||
|
||||
// `c` only captures t.0, therefore mutating t.1 is allowed.
|
||||
let t1 = &mut t.1;
|
||||
|
||||
c();
|
||||
*t1 = 20;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-disjoint-field-tuple.rs:6:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
|
||||
// Tests that if a closure uses indivual fields of the same object
|
||||
// then that case is handled properly.
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
struct Struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
s: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut s = Struct { x: 10, y: 10, s: String::new() };
|
||||
|
||||
let mut c = {
|
||||
s.x += 10;
|
||||
s.y += 42;
|
||||
s.s = String::from("new");
|
||||
};
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/disjoint-capture-in-same-closure.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// run-pass
|
||||
|
||||
// Test disjoint capture within an impl block
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
|
||||
struct Filter {
|
||||
div: i32,
|
||||
}
|
||||
impl Filter {
|
||||
fn allowed(&self, x: i32) -> bool {
|
||||
x % self.div == 1
|
||||
}
|
||||
}
|
||||
|
||||
struct Data {
|
||||
filter: Filter,
|
||||
list: Vec<i32>,
|
||||
}
|
||||
impl Data {
|
||||
fn update(&mut self) {
|
||||
// The closure passed to filter only captures self.filter,
|
||||
// therefore mutating self.list is allowed.
|
||||
self.list.retain(
|
||||
|v| self.filter.allowed(*v),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut d = Data { filter: Filter { div: 3 }, list: Vec::new() };
|
||||
|
||||
for i in 1..10 {
|
||||
d.list.push(i);
|
||||
}
|
||||
|
||||
d.update();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/filter-on-struct-member.rs:5:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// run-pass
|
||||
|
||||
// Test that closures can catpure paths that are more precise than just one level
|
||||
// from the root variable.
|
||||
//
|
||||
// If the closures can handle such precison we should be able to mutate one path in the closure
|
||||
// while being able to mutate another path outside the closure, where the two paths are disjoint
|
||||
// after applying two projections on the root variable.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![allow(unused)]
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
struct Wrapper {
|
||||
p: Point,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut w = Wrapper { p: Point { x: 10, y: 10 } };
|
||||
|
||||
let mut c = || {
|
||||
w.p.x += 20;
|
||||
};
|
||||
|
||||
// `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`.
|
||||
let py = &mut w.p.y;
|
||||
c();
|
||||
|
||||
*py = 20
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/multilevel-path-1.rs:10:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![allow(unused)]
|
||||
|
||||
// If the closures can handle such precison we should be able to read one path in the closure
|
||||
// while being able mutate another path outside the closure, where the two paths are disjoint
|
||||
// after applying two projections on the root variable.
|
||||
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
struct Wrapper {
|
||||
p: Point,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut w = Wrapper { p: Point { x: 10, y: 10 } };
|
||||
|
||||
let c = || {
|
||||
println!("{}", w.p.x);
|
||||
};
|
||||
|
||||
// `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`.
|
||||
let py = &mut w.p.y;
|
||||
c();
|
||||
|
||||
*py = 20
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/multilevel-path-2.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![allow(unused)]
|
||||
|
||||
// Test that when `capture_disjoint_fields` is enabled we can read a path
|
||||
// both inside and outside the closure at the same time.
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
struct Wrapper {
|
||||
p: Point,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut w = Wrapper { p: Point { x: 10, y: 10 } };
|
||||
|
||||
let c = || {
|
||||
println!("{}", w.p.x);
|
||||
};
|
||||
|
||||
let px = &w.p.x;
|
||||
c();
|
||||
|
||||
println!("{}", px);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/multilevel-path-3.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// run-pass
|
||||
|
||||
// Test whether if we can do precise capture when using nested clsoure.
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
|
||||
//~| NOTE: `#[warn(incomplete_features)]` on by default
|
||||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 5, y: 20 };
|
||||
|
||||
// c1 should capture `p.x` via immutable borrow and
|
||||
// `p.y` via mutable borrow.
|
||||
let mut c1 = || {
|
||||
println!("{}", p.x);
|
||||
|
||||
let incr = 10;
|
||||
|
||||
let mut c2 = || p.y += incr;
|
||||
c2();
|
||||
|
||||
println!("{}", p.y);
|
||||
};
|
||||
|
||||
c1();
|
||||
|
||||
// This should not throw an error because `p.x` is borrowed via Immutable borrow,
|
||||
// and multiple immutable borrow of the same place are allowed.
|
||||
let px = &p.x;
|
||||
|
||||
println!("{}", px);
|
||||
|
||||
c1();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/nested-closure.rs:5:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue