about summary refs log tree commit diff
path: root/tests/ui/rfcs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-27 18:51:43 +0000
committerbors <bors@rust-lang.org>2023-10-27 18:51:43 +0000
commit59bb9505bc0d0c9fbf9b5daf052bf033b63e5cc0 (patch)
treea3d662922a04455e5722399fcf049c9db4a54831 /tests/ui/rfcs
parent10143e781b3ae63240b96cabe13cc33671ccb13a (diff)
parent479fb4beb62788d904ec4cd50c79b858f54b662b (diff)
downloadrust-59bb9505bc0d0c9fbf9b5daf052bf033b63e5cc0.tar.gz
rust-59bb9505bc0d0c9fbf9b5daf052bf033b63e5cc0.zip
Auto merge of #103208 - cjgillot:match-fake-read, r=oli-obk,RalfJung
Allow partially moved values in match

This PR attempts to unify the behaviour between `let _ = PLACE`, `let _: TY = PLACE;` and `match PLACE { _ => {} }`.
The logical conclusion is that the `match` version should not check for uninitialised places nor check that borrows are still live.

The `match PLACE {}` case is handled by keeping a `FakeRead` in the unreachable fallback case to verify that `PLACE` has a legal value.

Schematically, `match PLACE { arms }` in surface rust becomes in MIR:
```rust
PlaceMention(PLACE)
match PLACE {
  // Decision tree for the explicit arms
  arms,
  // An extra fallback arm
  _ => {
    FakeRead(ForMatchedPlace, PLACE);
    unreachable
  }
}
```

`match *borrow { _ => {} }` continues to check that `*borrow` is live, but does not read the value.
`match *borrow {}` both checks that `*borrow` is live, and fake-reads the value.

Continuation of ~https://github.com/rust-lang/rust/pull/102256~ ~https://github.com/rust-lang/rust/pull/104844~

Fixes https://github.com/rust-lang/rust/issues/99180 https://github.com/rust-lang/rust/issues/53114
Diffstat (limited to 'tests/ui/rfcs')
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr14
-rw-r--r--tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr5
2 files changed, 9 insertions, 10 deletions
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
index d27fde58244..087e54244b3 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-guard-if-let-chain.rs:12:27
+  --> $DIR/move-guard-if-let-chain.rs:12:23
    |
 LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
@@ -7,7 +7,7 @@ LL |     let x: Box<_> = Box::new(1);
 LL |         (1, 2) if let y = x && c => (),
    |                       - value moved here
 LL |         (1, 2) if let z = x => (),
-   |                           ^ value used here after move
+   |                       ^ value used here after move
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -15,7 +15,7 @@ LL |         (1, 2) if let ref y = x && c => (),
    |                       +++
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-guard-if-let-chain.rs:36:27
+  --> $DIR/move-guard-if-let-chain.rs:36:23
    |
 LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
@@ -23,7 +23,7 @@ LL |     let x: Box<_> = Box::new(1);
 LL |         (1, _) if let y = x && c => (),
    |                       - value moved here
 LL |         (_, 2) if let z = x => (),
-   |                           ^ value used here after move
+   |                       ^ value used here after move
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -31,15 +31,13 @@ LL |         (1, _) if let ref y = x && c => (),
    |                       +++
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-guard-if-let-chain.rs:59:36
+  --> $DIR/move-guard-if-let-chain.rs:59:32
    |
 LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 ...
 LL |         (1, _) | (_, 2) if let y = x && c => (),
-   |                                -   ^ value used here after move
-   |                                |
-   |                                value moved here
+   |                                ^ value used here after move
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
index e97fdcce1c1..9dc339abc06 100644
--- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
+++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
@@ -1,13 +1,14 @@
 error[E0382]: use of moved value: `a`
-  --> $DIR/dbg-macro-move-semantics.rs:9:18
+  --> $DIR/dbg-macro-move-semantics.rs:9:13
    |
 LL |     let a = NoCopy(0);
    |         - move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait
 LL |     let _ = dbg!(a);
    |             ------- value moved here
 LL |     let _ = dbg!(a);
-   |                  ^ value used here after move
+   |             ^^^^^^^ value used here after move
    |
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error