about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/ui/closures/2229_closure_analysis/by_value.rs41
-rw-r--r--src/test/ui/closures/2229_closure_analysis/by_value.stderr67
-rw-r--r--src/test/ui/closures/2229_closure_analysis/move_closure.rs72
-rw-r--r--src/test/ui/closures/2229_closure_analysis/move_closure.stderr147
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs28
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs47
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs47
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs63
-rw-r--r--src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr102
12 files changed, 657 insertions, 0 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/by_value.rs b/src/test/ui/closures/2229_closure_analysis/by_value.rs
new file mode 100644
index 00000000000..1007fb582e5
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/by_value.rs
@@ -0,0 +1,41 @@
+// Test that we handle derferences properly when only some of the captures are being moved with
+// `capture_disjoint_fields` enabled.
+
+
+#![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, Default)]
+struct SomeLargeType;
+struct MuchLargerType([SomeLargeType; 32]);
+
+// Ensure that we don't capture any derefs when moving captures into the closures,
+// i.e. only data from the enclosing stack is moved.
+fn big_box() {
+    let s = MuchLargerType(Default::default());
+    let b = Box::new(s);
+    let t = (b, 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 p = t.0.0;
+        //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
+        //~| NOTE: Min Capture t[(0, 0)] -> ByValue
+        println!("{} {:?}", t.1, p);
+        //~^ NOTE: Capturing t[(1, 0)] -> ImmBorrow
+        //~| NOTE: Min Capture t[(1, 0)] -> ImmBorrow
+    };
+
+    c();
+}
+
+fn main() {
+    big_box();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/by_value.stderr b/src/test/ui/closures/2229_closure_analysis/by_value.stderr
new file mode 100644
index 00000000000..fe04dbef6d8
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/by_value.stderr
@@ -0,0 +1,67 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/by_value.rs:22: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/by_value.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
+
+error: First Pass analysis includes:
+  --> $DIR/by_value.rs:25:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let p = t.0.0;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
+  --> $DIR/by_value.rs:28:17
+   |
+LL |         let p = t.0.0;
+   |                 ^^^^^
+note: Capturing t[(1, 0)] -> ImmBorrow
+  --> $DIR/by_value.rs:31:29
+   |
+LL |         println!("{} {:?}", t.1, p);
+   |                             ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/by_value.rs:25:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let p = t.0.0;
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture t[(0, 0)] -> ByValue
+  --> $DIR/by_value.rs:28:17
+   |
+LL |         let p = t.0.0;
+   |                 ^^^^^
+note: Min Capture t[(1, 0)] -> ImmBorrow
+  --> $DIR/by_value.rs:31:29
+   |
+LL |         println!("{} {:?}", t.1, p);
+   |                             ^^^
+
+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/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/move_closure.rs
new file mode 100644
index 00000000000..8bdc999ca3c
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/move_closure.rs
@@ -0,0 +1,72 @@
+// Test that move closures drop derefs with `capture_disjoint_fields` enabled.
+
+#![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)]
+
+// Test we truncate derefs properly
+fn simple_ref() {
+    let mut s = 10;
+    let ref_s = &mut s;
+
+    let mut c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    move || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        *ref_s += 10;
+        //~^ NOTE: Capturing ref_s[Deref] -> ByValue
+        //~| NOTE: Min Capture ref_s[] -> ByValue
+    };
+    c();
+}
+
+// Test we truncate derefs properly
+fn struct_contains_ref_to_another_struct() {
+    struct S(String);
+    struct T<'a>(&'a mut S);
+
+    let mut s = S("s".into());
+    let t = T(&mut s);
+
+    let mut c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    move || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        t.0.0 = "new s".into();
+        //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
+        //~| NOTE: Min Capture t[(0, 0)] -> ByValue
+    };
+
+    c();
+}
+
+// Test that we don't reduce precision when there is nothing deref.
+fn no_ref() {
+    struct S(String);
+    struct T(S);
+
+    let t = T(S("s".into()));
+    let mut c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    move || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        t.0.0 = "new S".into();
+        //~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
+        //~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
+    };
+    c();
+}
+
+fn main() {
+    simple_ref();
+    struct_contains_ref_to_another_struct();
+    no_ref();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
new file mode 100644
index 00000000000..a745f14598e
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
@@ -0,0 +1,147 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/move_closure.rs:14:17
+   |
+LL |     let mut 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
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/move_closure.rs:35:17
+   |
+LL |     let mut 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
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/move_closure.rs:55:17
+   |
+LL |     let mut 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/move_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
+
+error: First Pass analysis includes:
+  --> $DIR/move_closure.rs:17:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         *ref_s += 10;
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing ref_s[Deref] -> ByValue
+  --> $DIR/move_closure.rs:20:9
+   |
+LL |         *ref_s += 10;
+   |         ^^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/move_closure.rs:17:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         *ref_s += 10;
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture ref_s[] -> ByValue
+  --> $DIR/move_closure.rs:20:9
+   |
+LL |         *ref_s += 10;
+   |         ^^^^^^
+
+error: First Pass analysis includes:
+  --> $DIR/move_closure.rs:38:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         t.0.0 = "new s".into();
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
+  --> $DIR/move_closure.rs:41:9
+   |
+LL |         t.0.0 = "new s".into();
+   |         ^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/move_closure.rs:38:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         t.0.0 = "new s".into();
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture t[(0, 0)] -> ByValue
+  --> $DIR/move_closure.rs:41:9
+   |
+LL |         t.0.0 = "new s".into();
+   |         ^^^^^
+
+error: First Pass analysis includes:
+  --> $DIR/move_closure.rs:58:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         t.0.0 = "new S".into();
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing t[(0, 0),(0, 0)] -> ByValue
+  --> $DIR/move_closure.rs:61:9
+   |
+LL |         t.0.0 = "new S".into();
+   |         ^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/move_closure.rs:58:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         t.0.0 = "new S".into();
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture t[(0, 0),(0, 0)] -> ByValue
+  --> $DIR/move_closure.rs:61:9
+   |
+LL |         t.0.0 = "new S".into();
+   |         ^^^^^
+
+error: aborting due to 9 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/run_pass/by_value.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
new file mode 100644
index 00000000000..9a93e6cf1e1
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
@@ -0,0 +1,28 @@
+// run-pass
+
+// Test that ByValue captures compile sucessefully especially when the captures are
+// derefenced within the closure.
+
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+
+#[derive(Debug, Default)]
+struct SomeLargeType;
+struct MuchLargerType([SomeLargeType; 32]);
+
+fn big_box() {
+    let s = MuchLargerType(Default::default());
+    let b = Box::new(s);
+    let t = (b, 10);
+
+    let c = || {
+        let p = t.0.0;
+        println!("{} {:?}", t.1, p);
+    };
+
+    c();
+}
+
+fn main() {
+    big_box();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr
new file mode 100644
index 00000000000..98715c6b943
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr
@@ -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/by_value.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
+
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
new file mode 100644
index 00000000000..83ed1c28462
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
@@ -0,0 +1,47 @@
+// run-pass
+
+// Test that move closures compile properly with `capture_disjoint_fields` enabled.
+
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+
+fn simple_ref() {
+    let mut s = 10;
+    let ref_s = &mut s;
+
+    let mut c = move || {
+        *ref_s += 10;
+    };
+    c();
+}
+
+fn struct_contains_ref_to_another_struct() {
+    struct S(String);
+    struct T<'a>(&'a mut S);
+
+    let mut s = S("s".into());
+    let t = T(&mut s);
+
+    let mut c = move || {
+        t.0.0 = "new s".into();
+    };
+
+    c();
+}
+
+fn no_ref() {
+    struct S(String);
+    struct T(S);
+
+    let t = T(S("s".into()));
+    let mut c = move || {
+        t.0.0 = "new S".into();
+    };
+    c();
+}
+
+fn main() {
+    simple_ref();
+    struct_contains_ref_to_another_struct();
+    no_ref();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr
new file mode 100644
index 00000000000..724b683bfbf
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr
@@ -0,0 +1,21 @@
+warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/move_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: variable does not need to be mutable
+  --> $DIR/move_closure.rs:36:9
+   |
+LL |     let mut t = T(S("s".into()));
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+   |
+   = note: `#[warn(unused_mut)]` on by default
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
new file mode 100644
index 00000000000..f6e9862b26c
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
@@ -0,0 +1,47 @@
+// run-pass
+
+// Test that we can use raw ptrs when using `capture_disjoint_fields`.
+
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+
+#[derive(Debug)]
+struct S {
+    s: String,
+    t: String,
+}
+
+struct T(*const S);
+
+fn unsafe_imm() {
+    let s = "".into();
+    let t = "".into();
+    let my_speed: Box<S> = Box::new(S { s, t });
+
+    let p : *const S = Box::into_raw(my_speed);
+    let t = T(p);
+
+    let c = || unsafe {
+        println!("{:?}", (*t.0).s);
+    };
+
+    c();
+}
+
+fn unsafe_mut() {
+    let s = "".into();
+    let t = "".into();
+    let mut my_speed: Box<S> = Box::new(S { s, t });
+    let p : *mut S = &mut *my_speed;
+
+    let c = || {
+        let x = unsafe { &mut (*p).s };
+        *x = "s".into();
+    };
+    c();
+}
+
+fn main() {
+    unsafe_mut();
+    unsafe_imm();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr
new file mode 100644
index 00000000000..c64c8b72e81
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr
@@ -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/unsafe_ptr.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
+
diff --git a/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs
new file mode 100644
index 00000000000..79d3ecc2d2b
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs
@@ -0,0 +1,63 @@
+// Test that we restrict precision of a capture when we access a raw ptr,
+// i.e. the capture doesn't deref the raw ptr.
+
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+//~| `#[warn(incomplete_features)]` on by default
+//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+#![feature(rustc_attrs)]
+
+#[derive(Debug)]
+struct S {
+    s: String,
+    t: String,
+}
+
+struct T(*const S);
+
+fn unsafe_imm() {
+    let s = "".into();
+    let t = "".into();
+    let my_speed: Box<S> = Box::new(S { s, t });
+
+    let p : *const S = Box::into_raw(my_speed);
+    let t = T(p);
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+     || unsafe {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        println!("{:?}", (*t.0).s);
+        //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
+        //~| NOTE: Min Capture t[(0, 0)] -> ImmBorrow
+    };
+
+    c();
+}
+
+fn unsafe_mut() {
+    let s = "".into();
+    let t = "".into();
+    let mut my_speed: Box<S> = Box::new(S { s, t });
+    let p : *mut S = &mut *my_speed;
+
+    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 = unsafe { &mut (*p).s };
+        //~^ NOTE: Capturing p[Deref,(0, 0)] -> ImmBorrow
+        //~| NOTE: Min Capture p[] -> ImmBorrow
+        *x = "s".into();
+    };
+    c();
+}
+
+fn main() {
+    unsafe_mut();
+    unsafe_imm();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
new file mode 100644
index 00000000000..4508b2426e8
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
@@ -0,0 +1,102 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/unsafe_ptr.rs:26: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
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/unsafe_ptr.rs:46: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/unsafe_ptr.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: First Pass analysis includes:
+  --> $DIR/unsafe_ptr.rs:29:6
+   |
+LL | /      || unsafe {
+LL | |
+LL | |
+LL | |         println!("{:?}", (*t.0).s);
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
+  --> $DIR/unsafe_ptr.rs:32:26
+   |
+LL |         println!("{:?}", (*t.0).s);
+   |                          ^^^^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/unsafe_ptr.rs:29:6
+   |
+LL | /      || unsafe {
+LL | |
+LL | |
+LL | |         println!("{:?}", (*t.0).s);
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture t[(0, 0)] -> ImmBorrow
+  --> $DIR/unsafe_ptr.rs:32:26
+   |
+LL |         println!("{:?}", (*t.0).s);
+   |                          ^^^^^^^^
+
+error: First Pass analysis includes:
+  --> $DIR/unsafe_ptr.rs:49:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let x = unsafe { &mut (*p).s };
+...  |
+LL | |         *x = "s".into();
+LL | |     };
+   | |_____^
+   |
+note: Capturing p[Deref,(0, 0)] -> ImmBorrow
+  --> $DIR/unsafe_ptr.rs:52:31
+   |
+LL |         let x = unsafe { &mut (*p).s };
+   |                               ^^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/unsafe_ptr.rs:49:5
+   |
+LL | /     || {
+LL | |
+LL | |
+LL | |         let x = unsafe { &mut (*p).s };
+...  |
+LL | |         *x = "s".into();
+LL | |     };
+   | |_____^
+   |
+note: Min Capture p[] -> ImmBorrow
+  --> $DIR/unsafe_ptr.rs:52:31
+   |
+LL |         let x = unsafe { &mut (*p).s };
+   |                               ^^^^^^
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0658`.