Rollup merge of #133093 - est31:let_chains_tests, r=traviscross

Let chains tests

Filing this as this marks off two of the open issues in #132833:

* extending the tests for `move-guard-if-let-chain.rs` and `conflicting_bindings.rs` to have chains with multiple let's (one implementation could for example search for the first `let` and then terminate).
* An instance where a temporary lives shorter than with nested ifs, breaking compilation: #103476. This was fixed in the end by the if let rescoping work.

Closes #103476
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-11-17 23:56:10 +08:00 committed by GitHub
commit ccc3f862d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 68 additions and 6 deletions

View File

@ -10,6 +10,8 @@ fn main() {
//~^ ERROR: mutable more than once
if let Some(ref mut y @ ref mut z) = x && true {}
//~^ ERROR: mutable more than once
if let Some(_) = Some(()) && let Some(ref mut y @ ref mut z) = x && true {}
//~^ ERROR: mutable more than once
while let Some(ref mut y @ ref mut z) = x {}
//~^ ERROR: mutable more than once
while let Some(ref mut y @ ref mut z) = x && true {}

View File

@ -31,7 +31,15 @@ LL | if let Some(ref mut y @ ref mut z) = x && true {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:13:20
--> $DIR/conflicting_bindings.rs:13:43
|
LL | if let Some(_) = Some(()) && let Some(ref mut y @ ref mut z) = x && true {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
| |
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:15:20
|
LL | while let Some(ref mut y @ ref mut z) = x {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@ -39,7 +47,7 @@ LL | while let Some(ref mut y @ ref mut z) = x {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:15:20
--> $DIR/conflicting_bindings.rs:17:20
|
LL | while let Some(ref mut y @ ref mut z) = x && true {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@ -47,7 +55,7 @@ LL | while let Some(ref mut y @ ref mut z) = x && true {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:18:9
--> $DIR/conflicting_bindings.rs:20:9
|
LL | ref mut y @ ref mut z => {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
@ -55,12 +63,12 @@ LL | ref mut y @ ref mut z => {}
| value is mutably borrowed by `y` here
error: cannot borrow value as mutable more than once at a time
--> $DIR/conflicting_bindings.rs:21:24
--> $DIR/conflicting_bindings.rs:23:24
|
LL | () if let Some(ref mut y @ ref mut z) = x => {}
| ^^^^^^^^^ --------- value is mutably borrowed by `z` here
| |
| value is mutably borrowed by `y` here
error: aborting due to 8 previous errors
error: aborting due to 9 previous errors

View File

@ -94,4 +94,15 @@ fn use_in_arm_ok(c: bool) {
};
}
fn use_in_same_chain(c: bool) {
let x: Box<_> = Box::new(1);
let v = (1, 2);
match v {
(1, 2) if let y = x && c && let z = x => false, //~ ERROR use of moved value: `x`
_ => true,
};
}
fn main() {}

View File

@ -60,6 +60,22 @@ help: borrow this binding in the pattern to avoid moving the value
LL | (1, 2) if let ref y = x && c => false,
| +++
error: aborting due to 4 previous errors
error[E0382]: use of moved value: `x`
--> $DIR/move-guard-if-let-chain.rs:103:41
|
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 && let z = x => false,
| - ^ value used here after move
| |
| value moved here
|
help: borrow this binding in the pattern to avoid moving the value
|
LL | (1, 2) if let ref y = x && c && let z = x => false,
| +++
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0382`.

View File

@ -0,0 +1,25 @@
// issue-103476
//@ compile-flags: -Zlint-mir -Zunstable-options
//@ edition: 2024
//@ check-pass
#![feature(let_chains)]
#![allow(irrefutable_let_patterns)]
struct Pd;
impl Pd {
fn it(&self) -> It {
todo!()
}
}
pub struct It<'a>(Box<dyn Tr<'a>>);
trait Tr<'a> {}
fn f(m: Option<Pd>) {
if let Some(n) = m && let it = n.it() {};
}
fn main() {}