diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-11-17 23:56:10 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-17 23:56:10 +0800 |
| commit | ccc3f862d6cbd027f8fe1438666ff09451854c26 (patch) | |
| tree | 9da432a53eb76f74e96cd1308be0a353dd3c46c1 | |
| parent | 0b157e88d7cf021c0ac537c4618b873f962772ac (diff) | |
| parent | f502dcea3839ff48a9960e07130f203bfd4a07b2 (diff) | |
| download | rust-ccc3f862d6cbd027f8fe1438666ff09451854c26.tar.gz rust-ccc3f862d6cbd027f8fe1438666ff09451854c26.zip | |
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
5 files changed, 68 insertions, 6 deletions
diff --git a/tests/ui/pattern/usefulness/conflicting_bindings.rs b/tests/ui/pattern/usefulness/conflicting_bindings.rs index 0b3e7ce9e9a..16737e0a894 100644 --- a/tests/ui/pattern/usefulness/conflicting_bindings.rs +++ b/tests/ui/pattern/usefulness/conflicting_bindings.rs @@ -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 {} diff --git a/tests/ui/pattern/usefulness/conflicting_bindings.stderr b/tests/ui/pattern/usefulness/conflicting_bindings.stderr index 679fc83e7f5..6f6504e6f64 100644 --- a/tests/ui/pattern/usefulness/conflicting_bindings.stderr +++ b/tests/ui/pattern/usefulness/conflicting_bindings.stderr @@ -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 diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs index 5c333cd7795..47653efffb7 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs @@ -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() {} 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 087e54244b3..123c5f19430 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 @@ -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`. diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs new file mode 100644 index 00000000000..389c76337f0 --- /dev/null +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs @@ -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() {} |
