about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-22 09:54:21 +0000
committerbors <bors@rust-lang.org>2023-04-22 09:54:21 +0000
commit21fab435da99d6ef14c1c870650ee976499564f3 (patch)
treeb95343fbae959c8db04ea9f9fcc6b0dc19bc24c0 /tests
parentccb6290e437bdeccbd509795f00a2390dad1fbeb (diff)
parent2870d269f5eb26e77ccf7718080afc62edaca8da (diff)
downloadrust-21fab435da99d6ef14c1c870650ee976499564f3.tar.gz
rust-21fab435da99d6ef14c1c870650ee976499564f3.zip
Auto merge of #104844 - cjgillot:mention-eval-place, r=jackh726,RalfJung
Evaluate place expression in `PlaceMention`

https://github.com/rust-lang/rust/pull/102256 introduces a `PlaceMention(place)` MIR statement which keep trace of `let _ = place` statements from surface rust, but without semantics.

This PR proposes to change the behaviour of `let _ =` patterns with respect to the borrow-checker to verify that the bound place is live.

Specifically, consider this code:
```rust
let _ = {
    let a = 5;
    &a
};
```

This passes borrowck without error on stable. Meanwhile, replacing `_` by `_: _` or `_p` errors with "error[E0597]: `a` does not live long enough", [see playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c448d25a7c205dc95a0967fe96bccce8).

This PR *does not* change how `_` patterns behave with respect to initializedness: it remains ok to bind a moved-from place to `_`.

The relevant test is `tests/ui/borrowck/let_underscore_temporary.rs`. Crater check found no regression.

For consistency, this PR changes miri to evaluate the place found in `PlaceMention`, and report eventual dangling pointers found within it.

r? `@RalfJung`
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/borrowck/let_underscore_temporary.rs30
-rw-r--r--tests/ui/borrowck/let_underscore_temporary.stderr79
-rw-r--r--tests/ui/span/send-is-not-static-std-sync-2.stderr2
3 files changed, 108 insertions, 3 deletions
diff --git a/tests/ui/borrowck/let_underscore_temporary.rs b/tests/ui/borrowck/let_underscore_temporary.rs
index 37b5c5d9d7a..835cd20798f 100644
--- a/tests/ui/borrowck/let_underscore_temporary.rs
+++ b/tests/ui/borrowck/let_underscore_temporary.rs
@@ -1,4 +1,4 @@
-// check-pass
+// check-fail
 
 fn let_underscore(string: &Option<&str>, mut num: Option<i32>) {
     let _ = if let Some(s) = *string { s.len() } else { 0 };
@@ -8,6 +8,7 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) {
         s
     } else {
         &mut 0
+        //~^ ERROR temporary value dropped while borrowed
     };
     let _ = if let Some(ref s) = num { s } else { &0 };
     let _ = if let Some(mut s) = num {
@@ -21,6 +22,33 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) {
         s
     } else {
         &mut 0
+        //~^ ERROR temporary value dropped while borrowed
+    };
+}
+
+fn let_ascribe(string: &Option<&str>, mut num: Option<i32>) {
+    let _: _ = if let Some(s) = *string { s.len() } else { 0 };
+    let _: _ = if let Some(s) = &num { s } else { &0 };
+    let _: _ = if let Some(s) = &mut num {
+        *s += 1;
+        s
+    } else {
+        &mut 0
+        //~^ ERROR temporary value dropped while borrowed
+    };
+    let _: _ = if let Some(ref s) = num { s } else { &0 };
+    let _: _ = if let Some(mut s) = num {
+        s += 1;
+        s
+    } else {
+        0
+    };
+    let _: _ = if let Some(ref mut s) = num {
+        *s += 1;
+        s
+    } else {
+        &mut 0
+        //~^ ERROR temporary value dropped while borrowed
     };
 }
 
diff --git a/tests/ui/borrowck/let_underscore_temporary.stderr b/tests/ui/borrowck/let_underscore_temporary.stderr
new file mode 100644
index 00000000000..74f3598c4d0
--- /dev/null
+++ b/tests/ui/borrowck/let_underscore_temporary.stderr
@@ -0,0 +1,79 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/let_underscore_temporary.rs:10:14
+   |
+LL |       let _ = if let Some(s) = &mut num {
+   |  _____________-
+LL | |         *s += 1;
+LL | |         s
+LL | |     } else {
+LL | |         &mut 0
+   | |              ^ creates a temporary value which is freed while still in use
+LL | |
+LL | |     };
+   | |     -
+   | |     |
+   | |_____temporary value is freed at the end of this statement
+   |       borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/let_underscore_temporary.rs:24:14
+   |
+LL |       let _ = if let Some(ref mut s) = num {
+   |  _____________-
+LL | |         *s += 1;
+LL | |         s
+LL | |     } else {
+LL | |         &mut 0
+   | |              ^ creates a temporary value which is freed while still in use
+LL | |
+LL | |     };
+   | |     -
+   | |     |
+   | |_____temporary value is freed at the end of this statement
+   |       borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/let_underscore_temporary.rs:36:14
+   |
+LL |       let _: _ = if let Some(s) = &mut num {
+   |  ________________-
+LL | |         *s += 1;
+LL | |         s
+LL | |     } else {
+LL | |         &mut 0
+   | |              ^ creates a temporary value which is freed while still in use
+LL | |
+LL | |     };
+   | |     -
+   | |     |
+   | |_____temporary value is freed at the end of this statement
+   |       borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/let_underscore_temporary.rs:50:14
+   |
+LL |       let _: _ = if let Some(ref mut s) = num {
+   |  ________________-
+LL | |         *s += 1;
+LL | |         s
+LL | |     } else {
+LL | |         &mut 0
+   | |              ^ creates a temporary value which is freed while still in use
+LL | |
+LL | |     };
+   | |     -
+   | |     |
+   | |_____temporary value is freed at the end of this statement
+   |       borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/span/send-is-not-static-std-sync-2.stderr b/tests/ui/span/send-is-not-static-std-sync-2.stderr
index b0267fa6f43..c825cc8d668 100644
--- a/tests/ui/span/send-is-not-static-std-sync-2.stderr
+++ b/tests/ui/span/send-is-not-static-std-sync-2.stderr
@@ -25,8 +25,6 @@ LL |     };
 error[E0597]: `x` does not live long enough
   --> $DIR/send-is-not-static-std-sync-2.rs:31:25
    |
-LL |     let (_tx, rx) = {
-   |          --- borrow later used here
 LL |         let x = 1;
    |             - binding `x` declared here
 LL |         let (tx, rx) = mpsc::channel();