Test cases for RFC 2229

This commit is contained in:
Aman Arora 2020-11-25 15:15:55 -05:00
parent 237ad12698
commit 01df56343b
28 changed files with 914 additions and 0 deletions

View file

@ -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();
}

View file

@ -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`.

View file

@ -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();
}

View file

@ -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`.

View file

@ -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
}

View file

@ -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`.

View file

@ -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();
}

View file

@ -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`.

View 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();
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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");
};
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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();
}

View file

@ -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