about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-01-28 15:09:06 +0900
committerGitHub <noreply@github.com>2021-01-28 15:09:06 +0900
commit84ad95be70d3a1b06ed537e4e7ec0c8e1086cb36 (patch)
tree145cd2a0e5fc77116cbab6a22882d17417bb970c /src
parent98226638fd014ec7786878a0b102448f3530bcdb (diff)
parentcf71d83bd22a9aac4757f9bc144b42f3bbff6aae (diff)
downloadrust-84ad95be70d3a1b06ed537e4e7ec0c8e1086cb36.tar.gz
rust-84ad95be70d3a1b06ed537e4e7ec0c8e1086cb36.zip
Rollup merge of #81062 - sexxi-goose:precise_capture_diagnostics, r=nikomatsakis
Improve diagnostics for Precise Capture

This is just the capture analysis part and borrow checker logging will updated as part of rust-lang/project-rfc-2229#8

Closes rust-lang/project-rfc-2229#22
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs35
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr77
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs30
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr65
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs35
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr65
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs33
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr62
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs52
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr70
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs27
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr70
-rw-r--r--src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr5
14 files changed, 628 insertions, 2 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs
new file mode 100644
index 00000000000..4368c830e1c
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs
@@ -0,0 +1,35 @@
+#![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)]
+
+#[derive(Debug)]
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn main() {
+    let p = Point { x: 10, y: 10 };
+    let q = Point { x: 10, y: 10 };
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+    //~^ First Pass analysis includes:
+    //~| Min Capture analysis includes:
+        println!("{:?}", p);
+        //~^ NOTE: Capturing p[] -> ImmBorrow
+        //~| NOTE: Min Capture p[] -> ImmBorrow
+        println!("{:?}", p.x);
+        //~^ NOTE: Capturing p[(0, 0)] -> ImmBorrow
+
+        println!("{:?}", q.x);
+        //~^ NOTE: Capturing q[(0, 0)] -> ImmBorrow
+        println!("{:?}", q);
+        //~^ NOTE: Capturing q[] -> ImmBorrow
+        //~| NOTE: Min Capture q[] -> ImmBorrow
+    };
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
new file mode 100644
index 00000000000..09255343af0
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
@@ -0,0 +1,77 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/capture-analysis-1.rs:17:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/capture-analysis-1.rs:1: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: First Pass analysis includes:
+  --> $DIR/capture-analysis-1.rs:20:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", p);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing p[] -> ImmBorrow
+  --> $DIR/capture-analysis-1.rs:23:26
+   |
+LL |         println!("{:?}", p);
+   |                          ^
+note: Capturing p[(0, 0)] -> ImmBorrow
+  --> $DIR/capture-analysis-1.rs:26:26
+   |
+LL |         println!("{:?}", p.x);
+   |                          ^^^
+note: Capturing q[(0, 0)] -> ImmBorrow
+  --> $DIR/capture-analysis-1.rs:29:26
+   |
+LL |         println!("{:?}", q.x);
+   |                          ^^^
+note: Capturing q[] -> ImmBorrow
+  --> $DIR/capture-analysis-1.rs:31:26
+   |
+LL |         println!("{:?}", q);
+   |                          ^
+
+error: Min Capture analysis includes:
+  --> $DIR/capture-analysis-1.rs:20:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         println!("{:?}", p);
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture p[] -> ImmBorrow
+  --> $DIR/capture-analysis-1.rs:23:26
+   |
+LL |         println!("{:?}", p);
+   |                          ^
+note: Min Capture q[] -> ImmBorrow
+  --> $DIR/capture-analysis-1.rs:31:26
+   |
+LL |         println!("{:?}", q);
+   |                          ^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs
new file mode 100644
index 00000000000..ab7fce6a430
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs
@@ -0,0 +1,30 @@
+#![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)]
+
+#[derive(Debug)]
+struct Point {
+    x: String,
+    y: i32,
+}
+
+fn main() {
+    let mut p = Point { x: String::new(), y: 10 };
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+    //~^ First Pass analysis includes:
+    //~| Min Capture analysis includes:
+        let _x = p.x;
+        //~^ NOTE: Capturing p[(0, 0)] -> ByValue
+        //~| NOTE: p[] captured as ByValue here
+        println!("{:?}", p);
+        //~^ NOTE: Capturing p[] -> ImmBorrow
+        //~| NOTE: Min Capture p[] -> ByValue
+        //~| NOTE: p[] used here
+    };
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
new file mode 100644
index 00000000000..0e48d6b300b
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
@@ -0,0 +1,65 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/capture-analysis-2.rs:16:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/capture-analysis-2.rs:1: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: First Pass analysis includes:
+  --> $DIR/capture-analysis-2.rs:19:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let _x = p.x;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing p[(0, 0)] -> ByValue
+  --> $DIR/capture-analysis-2.rs:22:18
+   |
+LL |         let _x = p.x;
+   |                  ^^^
+note: Capturing p[] -> ImmBorrow
+  --> $DIR/capture-analysis-2.rs:25:26
+   |
+LL |         println!("{:?}", p);
+   |                          ^
+
+error: Min Capture analysis includes:
+  --> $DIR/capture-analysis-2.rs:19:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let _x = p.x;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture p[] -> ByValue
+  --> $DIR/capture-analysis-2.rs:22:18
+   |
+LL |         let _x = p.x;
+   |                  ^^^ p[] captured as ByValue here
+...
+LL |         println!("{:?}", p);
+   |                          ^ p[] used here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs
new file mode 100644
index 00000000000..817ade899e2
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs
@@ -0,0 +1,35 @@
+#![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)]
+
+#[derive(Debug)]
+struct Child {
+    c: String,
+    d: String,
+}
+
+#[derive(Debug)]
+struct Parent {
+    b: Child,
+}
+
+fn main() {
+    let mut a = Parent { b: Child {c: String::new(), d: String::new()} };
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+    //~^ First Pass analysis includes:
+    //~| Min Capture analysis includes:
+        let _x = a.b.c;
+        //~^ NOTE: Capturing a[(0, 0),(0, 0)] -> ByValue
+        //~| NOTE: a[(0, 0)] captured as ByValue here
+        println!("{:?}", a.b);
+        //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow
+        //~| NOTE: Min Capture a[(0, 0)] -> ByValue
+        //~| NOTE: a[(0, 0)] used here
+    };
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
new file mode 100644
index 00000000000..263e9ca56eb
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
@@ -0,0 +1,65 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/capture-analysis-3.rs:21:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/capture-analysis-3.rs:1: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: First Pass analysis includes:
+  --> $DIR/capture-analysis-3.rs:24:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let _x = a.b.c;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing a[(0, 0),(0, 0)] -> ByValue
+  --> $DIR/capture-analysis-3.rs:27:18
+   |
+LL |         let _x = a.b.c;
+   |                  ^^^^^
+note: Capturing a[(0, 0)] -> ImmBorrow
+  --> $DIR/capture-analysis-3.rs:30:26
+   |
+LL |         println!("{:?}", a.b);
+   |                          ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/capture-analysis-3.rs:24:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let _x = a.b.c;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture a[(0, 0)] -> ByValue
+  --> $DIR/capture-analysis-3.rs:27:18
+   |
+LL |         let _x = a.b.c;
+   |                  ^^^^^ a[(0, 0)] captured as ByValue here
+...
+LL |         println!("{:?}", a.b);
+   |                          ^^^ a[(0, 0)] used here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs
new file mode 100644
index 00000000000..e8401299b30
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs
@@ -0,0 +1,33 @@
+#![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)]
+
+#[derive(Debug)]
+struct Child {
+    c: String,
+    d: String,
+}
+
+#[derive(Debug)]
+struct Parent {
+    b: Child,
+}
+
+fn main() {
+    let mut a = Parent { b: Child {c: String::new(), d: String::new()} };
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+    //~^ First Pass analysis includes:
+    //~| Min Capture analysis includes:
+        let _x = a.b;
+        //~^ NOTE: Capturing a[(0, 0)] -> ByValue
+        //~| NOTE: Min Capture a[(0, 0)] -> ByValue
+        println!("{:?}", a.b.c);
+        //~^ NOTE: Capturing a[(0, 0),(0, 0)] -> ImmBorrow
+    };
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
new file mode 100644
index 00000000000..f4605c1d51b
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
@@ -0,0 +1,62 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/capture-analysis-4.rs:21:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/capture-analysis-4.rs:1: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: First Pass analysis includes:
+  --> $DIR/capture-analysis-4.rs:24:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let _x = a.b;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing a[(0, 0)] -> ByValue
+  --> $DIR/capture-analysis-4.rs:27:18
+   |
+LL |         let _x = a.b;
+   |                  ^^^
+note: Capturing a[(0, 0),(0, 0)] -> ImmBorrow
+  --> $DIR/capture-analysis-4.rs:30:26
+   |
+LL |         println!("{:?}", a.b.c);
+   |                          ^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/capture-analysis-4.rs:24:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let _x = a.b;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture a[(0, 0)] -> ByValue
+  --> $DIR/capture-analysis-4.rs:27:18
+   |
+LL |         let _x = a.b;
+   |                  ^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs
new file mode 100644
index 00000000000..f81866bb7e0
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs
@@ -0,0 +1,52 @@
+#![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)]
+#![allow(unused)]
+
+#[derive(Debug)]
+struct Point {
+    x: i32,
+    y: i32,
+}
+#[derive(Debug)]
+struct Line {
+    p: Point,
+    q: Point
+}
+#[derive(Debug)]
+struct Plane {
+    a: Line,
+    b: Line,
+}
+
+fn main() {
+    let mut p = Plane {
+        a: Line {
+            p: Point { x: 1,y: 2 },
+            q: Point { x: 3,y: 4 },
+        },
+        b: Line {
+            p: Point { x: 1,y: 2 },
+            q: Point { x: 3,y: 4 },
+        }
+    };
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        let x = &p.a.p.x;
+        //~^ NOTE: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
+        p.b.q.y = 9;
+        //~^ NOTE: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow
+        //~| NOTE: p[] captured as MutBorrow here
+        println!("{:?}", p);
+        //~^ NOTE: Capturing p[] -> ImmBorrow
+        //~| NOTE: Min Capture p[] -> MutBorrow
+        //~| NOTE: p[] used here
+    };
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
new file mode 100644
index 00000000000..863f1009131
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
@@ -0,0 +1,70 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/deep-multilevel-struct.rs:36:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/deep-multilevel-struct.rs:1: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: First Pass analysis includes:
+  --> $DIR/deep-multilevel-struct.rs:39:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let x = &p.a.p.x;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
+  --> $DIR/deep-multilevel-struct.rs:42:18
+   |
+LL |         let x = &p.a.p.x;
+   |                  ^^^^^^^
+note: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow
+  --> $DIR/deep-multilevel-struct.rs:44:9
+   |
+LL |         p.b.q.y = 9;
+   |         ^^^^^^^
+note: Capturing p[] -> ImmBorrow
+  --> $DIR/deep-multilevel-struct.rs:47:26
+   |
+LL |         println!("{:?}", p);
+   |                          ^
+
+error: Min Capture analysis includes:
+  --> $DIR/deep-multilevel-struct.rs:39:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let x = &p.a.p.x;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture p[] -> MutBorrow
+  --> $DIR/deep-multilevel-struct.rs:44:9
+   |
+LL |         p.b.q.y = 9;
+   |         ^^^^^^^ p[] captured as MutBorrow here
+...
+LL |         println!("{:?}", p);
+   |                          ^ p[] used here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs
new file mode 100644
index 00000000000..fb03a02efa0
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs
@@ -0,0 +1,27 @@
+#![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)]
+#![allow(unused)]
+
+fn main() {
+    let mut t = (((1,2),(3,4)),((5,6),(7,8)));
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        let x = &t.0.0.0;
+        //~^ NOTE: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
+        t.1.1.1 = 9;
+        //~^ NOTE: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow
+        //~| NOTE: t[] captured as MutBorrow here
+        println!("{:?}", t);
+        //~^ NOTE: Min Capture t[] -> MutBorrow
+        //~| NOTE: Capturing t[] -> ImmBorrow
+        //~| NOTE: t[] used here
+    };
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
new file mode 100644
index 00000000000..252db444732
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
@@ -0,0 +1,70 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/deep-multilevel-tuple.rs:11:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/deep-multilevel-tuple.rs:1: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: First Pass analysis includes:
+  --> $DIR/deep-multilevel-tuple.rs:14:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let x = &t.0.0.0;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
+  --> $DIR/deep-multilevel-tuple.rs:17:18
+   |
+LL |         let x = &t.0.0.0;
+   |                  ^^^^^^^
+note: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow
+  --> $DIR/deep-multilevel-tuple.rs:19:9
+   |
+LL |         t.1.1.1 = 9;
+   |         ^^^^^^^
+note: Capturing t[] -> ImmBorrow
+  --> $DIR/deep-multilevel-tuple.rs:22:26
+   |
+LL |         println!("{:?}", t);
+   |                          ^
+
+error: Min Capture analysis includes:
+  --> $DIR/deep-multilevel-tuple.rs:14:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let x = &t.0.0.0;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture t[] -> MutBorrow
+  --> $DIR/deep-multilevel-tuple.rs:19:9
+   |
+LL |         t.1.1.1 = 9;
+   |         ^^^^^^^ t[] captured as MutBorrow here
+...
+LL |         println!("{:?}", t);
+   |                          ^ t[] used here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs
index aaff3531e58..a6b5e12d2ed 100644
--- a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs
+++ b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs
@@ -32,9 +32,11 @@ fn main() {
     //~| ERROR: Min Capture analysis includes:
         p.x += 10;
         //~^ NOTE: Capturing p[(0, 0)] -> MutBorrow
-        //~| NOTE: Min Capture p[] -> MutBorrow
+        //~| NOTE: p[] captured as MutBorrow here
         println!("{:?}", p);
         //~^ NOTE: Capturing p[] -> ImmBorrow
+        //~| NOTE: Min Capture p[] -> MutBorrow
+        //~| NOTE: p[] used here
     };
 
     c();
diff --git a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
index 30d3d5f504e..cbbc8792199 100644
--- a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
@@ -55,7 +55,10 @@ note: Min Capture p[] -> MutBorrow
   --> $DIR/simple-struct-min-capture.rs:33:9
    |
 LL |         p.x += 10;
-   |         ^^^
+   |         ^^^ p[] captured as MutBorrow here
+...
+LL |         println!("{:?}", p);
+   |                          ^ p[] used here
 
 error: aborting due to 3 previous errors; 1 warning emitted